ZQuest Classic Coverage Report


Directory: src/
File: src/zq/zquest.cpp
Date: 2026-01-19 09:21:43
Exec Total Coverage
Lines: 1961 13163 14.9%
Functions: 44 670 6.6%
Branches: 1114 10040 11.1%

Line Branch Exec Source
1 #include "allegro/gui.h"
2 #include "base/files.h"
3 #include "base/mapscr.h"
4 #include "dialog/edit_region.h"
5
6 #include <memory>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <cstring>
10 #include <sstream>
11 #include <ctype.h>
12 #include <assert.h>
13 #include <time.h>
14 #include <vector>
15 #include <filesystem>
16 #include <base/new_menu.h>
17
18 #include "dialog/info_lister.h"
19 #include "zq/commands.h"
20 #include "zq/render_map_view.h"
21 #ifdef __APPLE__
22 // malloc.h is deprecated, but malloc also lives in stdlib
23 #include <stdlib.h>
24 #else
25 #include <malloc.h>
26 #endif
27
28 #include "zalleg/zalleg.h"
29 #include "base/qrs.h"
30 #include "base/dmap.h"
31 #include "base/msgstr.h"
32 #include "base/packfile.h"
33 #include "base/cpool.h"
34 #include "base/autocombo.h"
35 #include "base/render.h"
36 #include "base/version.h"
37 #include "zq/autocombo/autopattern_base.h"
38 #include "zq/autocombo/pattern_basic.h"
39 #include "zq/autocombo/pattern_flatmtn.h"
40 #include "zq/autocombo/pattern_fence.h"
41 #include "zq/autocombo/pattern_cakemtn.h"
42 #include "zq/autocombo/pattern_relational.h"
43 #include "zq/autocombo/pattern_dungeoncarve.h"
44 #include "zq/autocombo/pattern_dormtn.h"
45 #include "zq/autocombo/pattern_tiling.h"
46 #include "zq/autocombo/pattern_replace.h"
47 #include "zq/autocombo/pattern_denseforest.h"
48 #include "zq/autocombo/pattern_extend.h"
49 #include "zq/render_hotkeys.h"
50 #include "zq/render_minimap.h"
51 #include "zq/render_tooltip.h"
52 #include "base/misctypes.h"
53 #include "parser/Compiler.h"
54 #include "base/zc_alleg.h"
55 #include "particles.h"
56 #include "dialog/combopool.h"
57 #include "dialog/alertfunc.h"
58 #include "zq/gui/edit_autocombo.h"
59
60 #include <al5_img.h>
61 #include <loadpng.h>
62 #include <fmt/format.h>
63
64 #include "dialog/cheat_codes.h"
65 #include "dialog/set_password.h"
66 #include "dialog/quest_rules.h"
67 #include "dialog/script_rules.h"
68 #include "dialog/headerdlg.h"
69 #include "dialog/ffc_editor.h"
70 #include "dialog/screen_data.h"
71 #include "dialog/edit_dmap.h"
72 #include "dialog/compilezscript.h"
73 #include "dialog/screen_enemies.h"
74 #include "dialog/enemypattern.h"
75 #include "dialog/sfxdata.h"
76 #include "dialog/mapstyles.h"
77 #include "dialog/externs.h"
78
79 #include "base/gui.h"
80 #include "gui/jwin_a5.h"
81 #include "gui/jwin.h"
82 #include "zc_list_data.h"
83 #include "gui/editbox.h"
84 #include "zq/zq_misc.h"
85 #include "zq/zq_tiles.h" // tile and combo code
86
87 #include "zq/zquest.h"
88 #include "zq/ffasm.h"
89 #include "zq/render.h"
90
91 // the following are used by both zelda.cc and zquest.cc
92 #include "base/zdefs.h"
93 #include "base/qrs.h"
94 #include "tiles.h"
95 #include "base/colors.h"
96 #include "base/qst.h"
97 #include "base/zsys.h"
98 #include "base/zapp.h"
99 #include "base/process_management.h"
100 #include "play_midi.h"
101 #include "sound/zcmusic.h"
102
103 #include "midi.h"
104 #include "sprite.h"
105 #include "fontsdat.h"
106 #include "base/jwinfsel.h"
107 #include "zq/zq_class.h"
108 #include "subscr.h"
109 #include "zq/zq_subscr.h"
110 #include "zc/ffscript.h"
111 #include "gui/EditboxNew.h"
112 #include "sfx.h"
113 #include "zq/zq_custom.h" // custom items and guys
114 #include "zq/zq_strings.h"
115 #include "zq/questReport.h"
116 #include <fstream>
117 #include "drawing.h"
118 #include "zconsole/ConsoleLogger.h"
119 #include "colorname.h"
120 #include "zq/zq_hotkey.h"
121 #include "zq/package.h"
122 #include "zq/zq_files.h"
123 #include "music_playback.h"
124
125 //Windows mmemory tools
126 #ifdef _WIN32
127 #include <windows.h>
128 #include <stdio.h>
129 #include <psapi.h>
130 #pragma comment(lib, "psapi.lib") // Needed to avoid linker issues. -Z
131 #endif
132
133 #ifdef __EMSCRIPTEN__
134 #include <emscripten/emscripten.h>
135 #endif
136
137 #define MIDI_TRACK_BUFFER_SIZE 50
138 extern CConsoleLoggerEx parser_console;
139
140 using ZScript::disassembled_script_data;
141 void write_script(vector<shared_ptr<ZScript::Opcode>> const& zasm, string& dest,
142 bool commented, map<string,disassembled_script_data>* scr_meta_map);
143
144 namespace fs = std::filesystem;
145
146 #if defined(ALLEGRO_WINDOWS)
147 static const char *data_path_name = "win_data_path";
148 static const char *midi_path_name = "win_midi_path";
149 static const char *image_path_name = "win_image_path";
150 static const char *tmusic_path_name = "win_tmusic_path";
151 static const char *last_quest_name = "win_last_quest";
152 static const char *qtname_name = "win_qtname%d";
153 static const char *qtpath_name = "win_qtpath%d";
154 #elif defined(ALLEGRO_LINUX)
155 static const char *data_path_name = "linux_data_path";
156 static const char *midi_path_name = "linux_midi_path";
157 static const char *image_path_name = "linux_image_path";
158 static const char *tmusic_path_name = "linux_tmusic_path";
159 static const char *last_quest_name = "linux_last_quest";
160 static const char *qtname_name = "linux_qtname%d";
161 static const char *qtpath_name = "linux_qtpath%d";
162 #elif defined(__APPLE__)
163 static const char *data_path_name = "macosx_data_path";
164 static const char *midi_path_name = "macosx_midi_path";
165 static const char *image_path_name = "macosx_image_path";
166 static const char *tmusic_path_name = "macosx_tmusic_path";
167 static const char *last_quest_name = "macosx_last_quest";
168 static const char *qtname_name = "macosx_qtname%d";
169 static const char *qtpath_name = "macosx_qtpath%d";
170 #endif
171
172 #include "base/win32.h"
173
174 #include "zq/zq_init.h"
175 #include "zq/zq_doors.h"
176 #include "zq/zq_cset.h"
177 #include "zinfo.h"
178
179 #ifdef _MSC_VER
180 #include <crtdbg.h>
181
182 #endif
183
184 // MSVC fix
185 #if _MSC_VER >= 1900
186 FILE _iob[] = { *stdin, *stdout, *stderr };
187 extern "C" FILE * __cdecl __iob_func(void) { return _iob; }
188 #endif
189
190 extern byte monochrome_console;
191
192 #include "zconsole/ConsoleLogger.h"
193
194 extern CConsoleLoggerEx zscript_coloured_console;
195
196 uint8_t console_is_open = 0;
197 bool is_zq_replay_test = false;
198
199 #include "base/util.h"
200
201 #ifdef __EMSCRIPTEN__
202 #include "base/emscripten_utils.h"
203 #endif
204
205 using namespace util;
206
207 using std::vector;
208 using std::map;
209 using std::stringstream;
210
211 12 FFScript FFCore;
212
213 void load_size_poses();
214 void do_previewtext();
215 bool do_slots(vector<shared_ptr<ZScript::Opcode>> const& zasm,
216 map<string, disassembled_script_data> &scripts, int assign_mode);
217
218 int32_t tooltip_timer=0, tooltip_maxtimer=30, tooltip_current_ffc=0;
219 int32_t combobrushoverride=-1;
220 ComboPosition mouse_combo_pos;
221
222 int32_t original_playing_field_offset=0;
223 12 int32_t playing_field_offset=original_playing_field_offset;
224 int32_t passive_subscreen_height=56;
225
226 bool disable_saving=false, OverwriteProtection;
227 bool halt=false;
228 bool show_sprites=true;
229 bool show_hitboxes = false;
230 bool zq_ignore_item_ownership = true;
231
232 // Used to find FFC script names
233 vector<string> asffcscripts;
234 vector<string> asglobalscripts;
235 vector<string> asitemscripts;
236 vector<string> asnpcscripts;
237 vector<string> aseweaponscripts;
238 vector<string> aslweaponscripts;
239 vector<string> asplayerscripts;
240 vector<string> asdmapscripts;
241 vector<string> asscreenscripts;
242 vector<string> asitemspritescripts;
243 vector<string> ascomboscripts;
244 vector<string> asgenericscripts;
245 vector<string> assubscreenscripts;
246
247 vector<string> ZQincludePaths;
248
249 int32_t CSET_SIZE = 16;
250 int32_t CSET_SHFT = 4;
251 //editbox_data temp_eb_data;
252 /*
253 #define CSET(x) ((x)<<CSET_SHFT)
254 #define csBOSS 14
255 */
256
257 /*
258 enum { m_block, m_coords, m_flags, m_guy, m_warp, m_misc, m_layers,
259 m_menucount };
260 */
261 void update_combo_cycling();
262 void update_freeform_combos();
263
264 /*
265 #define MAXMICE 14
266 #define MAXARROWS 8
267 #define SHADOW_DEPTH 2
268 */
269 int32_t coord_timer=0, coord_frame=0;
270 int32_t blackout_color, zq_screen_w, zq_screen_h;
271 int32_t draw_mode=0;
272
273 12 size_and_pos minimap;
274 12 size_and_pos real_minimap;
275
276 12 size_and_pos minimap_zoomed;
277 12 size_and_pos real_minimap_zoomed;
278
279 12 size_and_pos map_page_bar[9];
280 int32_t mappage_count = 9;
281
282 12 size_and_pos combolist[MAX_COMBO_COLS];
283 12 size_and_pos combolistscrollers[MAX_COMBO_COLS];
284 int32_t num_combo_cols = MAX_COMBO_COLS;
285
286 static bool zoom_in_btn_disabled;
287 static bool zoom_out_btn_disabled;
288 12 size_and_pos zoominbtn;
289 12 size_and_pos zoomoutbtn;
290 12 size_and_pos compactbtn;
291 12 size_and_pos mainbar;
292
293 12 size_and_pos screrrorpos;
294
295 12 size_and_pos comboaliaslist[MAX_COMBO_COLS];
296 12 size_and_pos comboalias_preview;
297 12 size_and_pos combopool_preview;
298 12 size_and_pos combopool_prevbtn;
299
300 12 size_and_pos combo_merge_btn;
301
302 12 size_and_pos combo_preview;
303 12 size_and_pos combo_preview2;
304 12 size_and_pos combo_preview_text1;
305 12 size_and_pos combo_preview_text2;
306 12 size_and_pos combolist_window;
307 12 size_and_pos drawmode_btn;
308 12 size_and_pos main_panel;
309 12 size_and_pos squares_panel;
310 12 size_and_pos preview_panel;
311 12 size_and_pos layer_panel;
312 12 size_and_pos preview_text;
313
314 12 size_and_pos favorites_window;
315 12 size_and_pos favorites_list;
316 12 size_and_pos favorites_x;
317 12 size_and_pos favorites_infobtn;
318 12 size_and_pos favorites_zoombtn;
319 12 size_and_pos favorites_pgleft;
320 12 size_and_pos favorites_pgright;
321
322 12 size_and_pos commands_window;
323 12 size_and_pos commands_list;
324 12 size_and_pos commands_x;
325 12 size_and_pos commands_infobtn;
326 12 size_and_pos commands_zoombtn;
327 12 size_and_pos commands_txt;
328
329 12 size_and_pos squarepanel_swap_btn;
330 12 size_and_pos squarepanel_up_btn;
331 12 size_and_pos squarepanel_down_btn;
332 12 size_and_pos itemsqr_pos;
333 12 size_and_pos flagsqr_pos;
334 12 size_and_pos stairsqr_pos;
335 12 size_and_pos warparrival_pos;
336 12 size_and_pos warpret_pos[4];
337 12 size_and_pos enemy_prev_pos;
338
339 12 size_and_pos txtoffs_single;
340 12 size_and_pos txtoffs_double_1;
341 12 size_and_pos txtoffs_double_2;
342 int32_t panel_align = 1;
343
344 int32_t command_buttonwidth = 88;
345 int32_t command_buttonheight = 19;
346
347 int32_t layerpanel_buttonwidth = 58;
348 int32_t layerpanel_buttonheight = 16;
349
350 int32_t layerpanel_checkbox_hei = 13;
351 int32_t layerpanel_checkbox_wid = 13;
352
353 int32_t favorite_combos[MAXFAVORITECOMBOS];
354 byte favorite_combo_modes[MAXFAVORITECOMBOS];
355 bool ShowFavoriteComboModes;
356 byte FavoriteComboPage;
357
358 char comboprev_buf[512] = {0};
359 char comboprev_buf2[512] = {0};
360 FONT* txfont;
361
362 int32_t mouse_scroll_h;
363
364 // 'mapscreen' refers to the area of the editor where the screen is drawn.
365 int32_t mapscreen_x, mapscreen_y, showedges, showallpanels;
366 // The scale of the entire mapscreen area. This varies based on compact/extended mode.
367 static int mapscreen_screenunit_scale;
368 // The scale of an individual screen being drawn. This is `mapscreen_screenunit_scale / Map.getViewSize()`.
369 static double mapscreen_single_scale;
370 // 4 is roughly the largest value where things render okay. Beyond that, our low bitmap resolution results in tons
371 // of downsampling. Let users go to 16 anyway.
372 static int mapscreen_num_screens_to_draw_max = 16;
373 // The valid layers for the current screen(s).
374 static bool mapscreen_valid_layers[6];
375
376 struct VisibleScreen
377 {
378 int dx, dy;
379 int xoff, yoff;
380 mapscr* scr;
381 int screen;
382 };
383 static std::vector<VisibleScreen> visible_screens;
384 static VisibleScreen* active_visible_screen = nullptr;
385
386 static void set_active_visible_screen(mapscr* scr)
387 {
388 active_visible_screen = nullptr;
389 for (auto& visible_screen : visible_screens)
390 {
391 if (visible_screen.scr == scr)
392 {
393 active_visible_screen = &visible_screen;
394 break;
395 }
396 }
397 }
398
399 static ComboPosition get_mapscreen_mouse_combo_pos()
400 {
401 int startxint = mapscreen_x+(showedges?int(16*mapscreen_single_scale):0);
402 int startyint = mapscreen_y+(showedges?int(16*mapscreen_single_scale):0);
403 int cx = (gui_mouse_x()-startxint)/(16*mapscreen_single_scale);
404 int cy = (gui_mouse_y()-startyint)/(16*mapscreen_single_scale);
405 return ComboPosition{cx, cy};
406 }
407
408 static void refresh_visible_screens()
409 {
410 int num_screens = Map.getViewSize();
411 int screen_width = mapscreenbmp->w * mapscreen_single_scale;
412 int screen_height = mapscreenbmp->h * mapscreen_single_scale;
413
414 visible_screens.clear();
415 for (int dx = 0; dx < num_screens; dx++)
416 {
417 for (int dy = 0; dy < num_screens; dy++)
418 {
419 int mx = Map.getViewScr()%16 + dx;
420 int my = Map.getViewScr()/16 + dy;
421 if (mx < 0 || mx >= 16 || my < 0 || my >= 9)
422 continue;
423
424 int screen = Map.getViewScr() + dx + dy * 16;
425 if (screen >= MAPSCRS)
426 continue;
427
428 mapscr* scr = Map.Scr(screen);
429 int offx = dx * screen_width;
430 int offy = dy * screen_height;
431 visible_screens.emplace_back(VisibleScreen{dx, dy, offx, offy, scr, screen});
432 }
433 }
434
435 for (int i = 0; i < 6; i++)
436 {
437 mapscreen_valid_layers[i] = false;
438 for (auto& vis_screen : visible_screens)
439 {
440 mapscreen_valid_layers[i] |= vis_screen.scr->layermap[i] > 0;
441 }
442 }
443 }
444
445 int32_t readsize, writesize;
446 bool fake_pack_writing=false;
447
448 int32_t showxypos_x;
449 int32_t showxypos_y;
450 int32_t showxypos_w;
451 int32_t showxypos_h;
452 int32_t showxypos_color;
453 int32_t showxypos_ffc=-1000;
454 bool showxypos_icon=false;
455
456 int32_t showxypos_cursor_x;
457 int32_t showxypos_cursor_y;
458 bool showxypos_cursor_icon=false;
459 int32_t showxypos_cursor_color;
460 bool showxypos_dummy = false;
461
462 bool canfill=true; //to prevent double-filling (which stops undos)
463 int32_t lens_hint_item[MAXITEMS][2]; //aclk, aframe
464 int32_t lens_hint_weapon[MAXWPNS][5]; //aclk, aframe, dir, x, y
465 //int32_t mode, switch_mode, orig_mode;
466 int32_t tempmode=GFX_AUTODETECT;
467 RGB_MAP* zq_rgb_table;
468 MIDI *song=NULL;
469 BITMAP *mapscreenbmp, *screen2, *mouse_bmp[MOUSE_BMP_MAX][4], *mouse_bmp_1x[MOUSE_BMP_MAX][4], *icon_bmp[ICON_BMP_MAX][4], *flag_bmp[16][4], *select_bmp[2], *dmapbmp_small, *dmapbmp_large;
470 BITMAP *arrow_bmp[MAXARROWS],*brushbmp, *brushscreen; //*brushshadowbmp;
471 byte *colordata=NULL, *trashbuf=NULL;
472 itemdata *itemsbuf;
473 wpndata *wpnsbuf;
474 comboclass *combo_class_buf;
475 guydata *guysbuf;
476 item_drop_object item_drop_sets[MAXITEMDROPSETS];
477 midi_info Midi_Info;
478 bool zq_showpal=false;
479 bool is_compact = false;
480
481 int pixeldb = 1;
482 int infobg = 1;
483 bool large_merged_combopane = false;
484 bool compact_merged_combopane = true;
485 bool large_zoomed_fav = false;
486 bool compact_zoomed_fav = true;
487 bool large_zoomed_cmd = false;
488 bool compact_zoomed_cmd = true;
489
490 bool compact_square_panels = false;
491 int compact_active_panel = 0;
492
493 int combo_col_scale = 1;
494
495 std::vector<std::shared_ptr<zasm_script>> zasm_scripts;
496 script_data *ffscripts[NUMSCRIPTFFC];
497 script_data *itemscripts[NUMSCRIPTITEM];
498 script_data *guyscripts[NUMSCRIPTGUYS];
499 script_data *lwpnscripts[NUMSCRIPTWEAPONS];
500 script_data *ewpnscripts[NUMSCRIPTWEAPONS];
501 script_data *globalscripts[NUMSCRIPTGLOBAL];
502 script_data *genericscripts[NUMSCRIPTSGENERIC];
503 script_data *playerscripts[NUMSCRIPTHERO];
504 script_data *screenscripts[NUMSCRIPTSCREEN];
505 script_data *dmapscripts[NUMSCRIPTSDMAP];
506 script_data *itemspritescripts[NUMSCRIPTSITEMSPRITE];
507 script_data *comboscripts[NUMSCRIPTSCOMBODATA];
508 script_data *subscreenscripts[NUMSCRIPTSSUBSCREEN];
509
510 extern string zScript;
511 char zScriptBytes[512];
512 char zLastVer[512] = { 0 };
513 SAMPLE customsfxdata[WAV_COUNT];
514 uint8_t customsfxflag[WAV_COUNT>>3];
515 int32_t sfxdat=1;
516
517 int32_t onImport_ComboAlias();
518 int32_t onExport_ComboAlias();
519
520 void set_console_state();
521
522 void clearConsole()
523 {
524 if(!console_is_open) return;
525 zscript_coloured_console.cls(CConsoleLoggerEx::COLOR_BACKGROUND_BLACK);
526 zscript_coloured_console.gotoxy(0,0);
527 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
528 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"ZQuest Classic Logging Console\n");
529 }
530
531 void initConsole()
532 {
533 if(console_is_open) return;
534 console_is_open = 1;
535 set_console_state();
536 zscript_coloured_console.Create("ZQuest Classic Logging Console", 600, 200);
537 clearConsole();
538 }
539
540 11 void killConsole()
541 {
542
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(!console_is_open) return;
543 console_is_open = 0;
544 set_console_state();
545 zscript_coloured_console.kill();
546 11 }
547
548 int toggleConsole()
549 {
550 console_is_open ? killConsole() : initConsole();
551 zc_set_config("zquest","open_debug_console",console_is_open?1:0);
552 return D_O_K;
553 }
554
555 int showHotkeys()
556 {
557 hotkeys_run();
558 return D_O_K;
559 }
560
561 extern map_and_screen map_page[MAX_MAPPAGE_BTNS];
562
563 int32_t do_OpenQuest()
564 {
565 return onOpen();
566 }
567
568 int32_t do_NewQuest()
569 {
570 //clear the panel recent screen buttons to prevent crashes from invalid maps
571 for ( int32_t q = 0; q < 9; q++ )
572 {
573 map_page[q].map = 0;
574 map_page[q].screen = 0;
575 }
576 Map.setCurrMap(0);
577 Map.setCurrScr(0);
578 return onNew();
579 }
580
581 extern int CheckerCol1, CheckerCol2;
582 int32_t alignment_arrow_timer=0;
583 int32_t Flip=0,Combo=0,CSet=2,current_combolist=0,current_comboalist=0,current_cpoollist=0,current_cautolist=0,current_mappage=0;
584 int32_t Flags=0,Flag=0,menutype=(m_block);
585 int MouseScroll = 0, SavePaths = 0, CycleOn = 0, ShowGrid = 0, ShowScreenGrid = 0, ShowRegionGrid = 0, GridColor = 15, ShowCurScreenOutline = 1,
586 CmbCursorCol = 15, TilePgCursorCol = 15, CmbPgCursorCol = 15, TTipHLCol = 13,
587 TileProtection = 0, ComboProtection = 0, NoScreenPreview = 0, MMapCursorStyle = 0,
588 LayerDitherBG = -1, LayerDitherSz = 2, RulesetDialog = 0,
589 EnableTooltips = 0, TooltipsHighlight = 0, ShowFFScripts = 0, ShowSquares = 0,
590 ShowFFCs = 0, ShowInfo = 0, skipLayerWarning = 0,
591 DisableLPalShortcuts = 1, DisableCompileConsole = 0, numericalFlags = 0,
592 ActiveLayerHighlight = 0, DragCenterOfSquares = 0, SmartFFCPlacement = 0;
593 uint8_t InvalidBG = 0;
594 bool NoHighlightLayer0 = false;
595 // If true, uses "MapViewRTI" to draw editor screens. This allows for multiples palettes on the
596 // screen at once, and for higher resolution.
597 // Note: this is the default currently, and eventually the option should be removed and the
598 // "low-quality" rendering removed. Hasn't been done just yet just in case this causes regressions.
599 bool HighQualityScreenRendering = true;
600 int32_t FlashWarpSquare = -1, FlashWarpClk = 0; // flash the destination warp return when ShowSquares is active
601 uint8_t ViewLayer3BG = 0, ViewLayer2BG = 0;
602 int32_t window_width, window_height;
603 bool ShowFPS = false, SaveDragResize = false, DragAspect = false, SaveWinPos=false;
604 bool allowHideMouse = false;
605 double aspect_ratio = LARGE_H / double(LARGE_W);
606 int window_min_width = 0, window_min_height = 0;
607 int32_t ComboBrush = 0; //show the brush instead of the normal mouse
608 int32_t ComboBrushPause = 0; //temporarily disable the combo brush
609 int32_t FloatBrush = 0; //makes the combo brush float a few pixels up and left
610 int AutoBrush = 0; //Drag to size the brush on the combo panes
611 bool AutoBrushRevert = false; //Revert after placing
612 int LinkedScroll = 0;
613 //complete with shadow
614 int32_t OpenLastQuest = 0; //makes the program reopen the quest that was
615 //open at the time you quit
616 int32_t ShowMisalignments = 0; //makes the program display arrows over combos that are
617 //not aligned with the next screen.
618 int32_t AnimationOn = 0; //animate the combos in zquest?
619 int32_t AutoBackupRetention = 0; //use auto-backup feature? if so, how many backups (1-10) to keep
620 int32_t AutoSaveInterval = 0; //how often a timed autosave is made (not overwriting the current file)
621 int32_t UncompressedAutoSaves = 0; //should timed saves be uncompressed/encrypted?
622 int32_t KeyboardRepeatDelay = 0; //the time in milliseconds after holding down a key that the key starts to repeat
623 int32_t KeyboardRepeatRate = 0; //the time in milliseconds between each repetition of a repeated key
624
625 time_t auto_save_time_start, auto_save_time_current;
626 double auto_save_time_diff = 0;
627 int32_t AutoSaveRetention = 0; //how many autosaves of a quest to keep
628 int32_t ImportMapBias = 0; //tells what has precedence on map importing
629 int32_t BrushWidth=1, BrushHeight=1;
630 bool saved = true, autosaved = true;
631 bool __debug=false;
632 int32_t LayerMaskInt[7]={0};
633 int32_t CurrentLayer=0;
634 int32_t DuplicateAction[4]={0};
635 int32_t OnlyCheckNewTilesForDuplicates = 0;
636 int32_t try_recovering_missing_scripts = 0;
637
638 uint8_t PreFillTileEditorPage = 0, PreFillComboEditorPage = 0;
639 int32_t DMapEditorLastMaptileUsed = 0;
640
641 /*
642 , HorizontalDuplicateAction;
643 int32_t VerticalDuplicateAction, BothDuplicateAction;
644 */
645 word msg_count = 0;
646 int32_t LeechUpdate = 0;
647 int32_t LeechUpdateTiles = 0;
648 int32_t SnapshotFormat = 0;
649 byte SnapshotScale = 0;
650
651 byte Color = 0;
652 extern int32_t jwin_pal[jcMAX];
653 int32_t gui_colorset=99;
654
655 static int32_t combo_apos=0; //currently selected combo alias
656 int32_t alias_origin=0;
657 int32_t alias_cset_mod=0;
658
659 static int32_t combo_pool_pos=0; //currently selected combo pool
660 bool weighted_cpool = true;
661 bool cpool_prev_visible = false;
662
663 static int32_t combo_auto_pos=0; //currently selected autocombo
664 byte cauto_height = 1;
665
666 bool trip=false;
667
668 int32_t fill_type=1;
669
670 bool first_save=false;
671 char *filepath,*midipath,*datapath,*imagepath,*tmusicpath,*last_timed_save;
672 string helpstr, zstringshelpstr;
673
674 ZCMUSIC *zcmusic = NULL;
675 ZCMIXER *zcmixer = NULL;
676 int32_t midi_volume = 255;
677 extern int32_t prv_mode;
678 int32_t prv_warp = 0;
679 int32_t prv_twon = 0;
680
681 int32_t Frameskip = 0, RequestedFPS = 60, zqUseWin32Proc = 1;
682 int32_t zqColorDepth = 8;
683
684 11 void set_last_timed_save(char const* buf)
685 {
686
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11 if(buf && buf[0])
687 {
688 if(buf != last_timed_save)
689 strcpy(last_timed_save, buf);
690 }
691 else
692 {
693 11 last_timed_save[0] = 0;
694 11 buf = nullptr;
695 }
696 11 zc_set_config("zquest","last_timed_save",buf);
697 11 }
698
699 17 void mark_save_dirty()
700 {
701 17 saved = false;
702 17 autosaved = false;
703 17 }
704
705 void loadlvlpal(int32_t level);
706 bool get_debug()
707 {
708 return __debug;
709 //return true;
710 }
711
712 void set_debug(bool d)
713 {
714 __debug=d;
715 return;
716 }
717
718 bool handle_quit()
719 {
720 if(onExit()==D_CLOSE)
721 return (exiting_program = true);
722 return false;
723 }
724 bool handle_close_btn_quit()
725 {
726 if(close_button_quit)
727 {
728 close_button_quit=false;
729 return handle_quit();
730 }
731 return false;
732 }
733 // **** Timers ****
734
735 volatile int32_t lastfps=0;
736 volatile int32_t framecnt=0;
737 size_t cpoolbrush_index = 0;
738
739 // quest data
740 12 zquestheader header;
741 byte midi_flags[MIDIFLAGS_SIZE];
742 byte music_flags[MUSICFLAGS_SIZE];
743 byte *quest_file;
744 int32_t msg_strings_size;
745 zctune *customtunes;
746 //emusic *enhancedMusic;
747 ZCHEATS zcheats;
748 byte use_cheats;
749 byte use_tiles;
750 // Note: may not be null-terminated (must refactor writecolordata to fix).
751 char palnames[MAXLEVELS][17];
752 char zquestdat_sig[52];
753 char qstdat_str[2048];
754
755 int32_t gme_track=0;
756
757 int32_t dlevel; // just here until gamedata is properly done
758
759 12 bool bad_version(int32_t ver)
760 {
761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(ver < 0x170)
762 return true;
763
764 12 return false;
765 12 }
766
767 // These are for drawing eyeballs correctly in combo_tile.
768 zfix HeroModifiedX()
769 {
770 return gui_mouse_x() - 7;
771 }
772 zfix HeroModifiedY()
773 {
774 return gui_mouse_y() - 7;
775 }
776
777
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu import_250_menu
778 48 {
779
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onImport_DMaps },
780
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Table", onImport_Combos },
781
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Alias", onImport_ComboAlias },
782 };
783
784
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu import_graphics
785 180 {
786
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palettes", onImport_Pals },
787
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
788
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Tileset (&Full)", onImport_Tiles },
789
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tile Pack", onImport_Tilepack },
790
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "T&ile Pack to...", onImport_Tilepack_To },
791
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
792
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Set (Range)", onImport_Combos },
793
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo Pack (Full, 1:1)", onImport_Combopack },
794
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo Pack to... (Dest)", onImport_Combopack_To },
795
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
796
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo &Alias Pack", onImport_Comboaliaspack },
797
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo A&lias Pack to...", onImport_Comboaliaspack_To },
798
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
799
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Doorsets", onImport_Doorset },
800 };
801
802
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu import_menu
803 120 {
804
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onImport_Guys },
805
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map", onImport_Map },
806
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onImport_DMaps },
807
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Strings (.tsv)", onImport_StringsTSV },
808
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "String Table (deprecated)", onImport_Msgs },
809
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
810
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Graphics", &import_graphics },
811
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
812
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2.50 (Broken)", &import_250_menu },
813 };
814
815
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu export_250_menu
816 60 {
817
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onExport_DMaps },
818
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Table", onExport_Combos },
819
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Alias", onExport_ComboAlias },
820
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Graphics Pack", onExport_ZGP },
821 };
822
823
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu zq_help_menu
824 36 {
825
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Editor Help", onHelp },
826
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Strings Help", onZstringshelp },
827 };
828
829
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu export_graphics
830 144 {
831
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palettes", onExport_Pals },
832
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
833
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Tileset (&Full)", onExport_Tiles },
834
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tile Pack", onExport_Tilepack },
835
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
836
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Set", onExport_Combos },
837
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo Pack", onExport_Combopack },
838
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
839
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo &Alias Pack", onExport_Comboaliaspack },
840
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
841
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Doorsets", onExport_Doorset },
842 };
843
844
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu export_menu
845 132 {
846 #ifdef _WIN32
847 { "&Package", onExport_Package },
848 #endif
849
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onExport_Guys },
850
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map", onExport_Map },
851
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onExport_DMaps },
852
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
853
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Strings (.tsv)", onExport_StringsTSV },
854
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "String Table (deprecated)", onExport_Msgs },
855
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
856
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Graphics", &export_graphics },
857
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
858
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2.50 (Broken)", &export_250_menu },
859 };
860
861
862
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu recent_menu
863 132 {
864
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
865
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
866
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
867
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
868
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
869
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
870
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
871
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
872
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
873
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
874 };
875 static char rec_menu_fullpaths[10][512];
876 static char rec_menu_strs[10][64];
877
878 int32_t customOpen(char const* path);
879 void do_recent_quest(uint32_t ind)
880 {
881 if(ind > 9) return;
882 strcpy(temppath, rec_menu_fullpaths[ind]);
883 customOpen(temppath);
884 }
885 int32_t do_RecentQuest_0() { do_recent_quest(0); return D_O_K; }
886 int32_t do_RecentQuest_1() { do_recent_quest(1); return D_O_K; }
887 int32_t do_RecentQuest_2() { do_recent_quest(2); return D_O_K; }
888 int32_t do_RecentQuest_3() { do_recent_quest(3); return D_O_K; }
889 int32_t do_RecentQuest_4() { do_recent_quest(4); return D_O_K; }
890 int32_t do_RecentQuest_5() { do_recent_quest(5); return D_O_K; }
891 int32_t do_RecentQuest_6() { do_recent_quest(6); return D_O_K; }
892 int32_t do_RecentQuest_7() { do_recent_quest(7); return D_O_K; }
893 int32_t do_RecentQuest_8() { do_recent_quest(8); return D_O_K; }
894 int32_t do_RecentQuest_9() { do_recent_quest(9); return D_O_K; }
895
896 2 void refresh_recent_menu()
897 {
898 2 int32_t (*procs[10])(void) = {
899 do_RecentQuest_0, do_RecentQuest_1, do_RecentQuest_2, do_RecentQuest_3,
900 do_RecentQuest_4, do_RecentQuest_5, do_RecentQuest_6,
901 do_RecentQuest_7, do_RecentQuest_8, do_RecentQuest_9
902 };
903
5/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
2 static MenuItem nilitem("---",nullptr,nullopt,true);
904
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 20 times.
22 for(auto q = 0; q < 10; ++q)
905 {
906 20 MenuItem& mit = *recent_menu.at(q);
907 20 bool valid = rec_menu_fullpaths[q][0] != '-';
908
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if(valid)
909 mit = MenuItem(rec_menu_strs[q],procs[q]);
910 20 else mit = nilitem;
911 20 }
912 2 }
913
914 1 void load_recent_quests()
915 {
916 1 char configname[64] = "rec_qst_";
917 1 char* ptr = &configname[strlen(configname)];
918 1 char buf[512] = {0};
919
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
11 for(auto q = 0; q < 10; ++q)
920 {
921 10 sprintf(ptr, "%d", q); //increment the configname value
922 10 char const* qst_str = zc_get_config("recent",configname,nullptr);
923
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(qst_str[0])
924 {
925 strncpy(rec_menu_fullpaths[q], qst_str, 511);
926 relativize_path(buf, rec_menu_fullpaths[q]);
927 if(strlen(buf) > 62)
928 {
929 buf[60] = buf[61] = buf[62] = '.'; //add "..." as the last 3 characters
930 }
931 strncpy(rec_menu_strs[q], buf, 63);
932 }
933 else
934 {
935 10 strcpy(rec_menu_fullpaths[q], "---");
936 10 strcpy(rec_menu_strs[q], "---");
937 }
938 10 rec_menu_fullpaths[q][511] = 0;
939 10 rec_menu_strs[q][63] = 0;
940 10 }
941 1 refresh_recent_menu();
942 1 }
943
944 void write_recent_quests()
945 {
946 char configname[64] = "rec_qst_";
947 char* ptr = &configname[strlen(configname)];
948 for(auto q = 0; q < 10; ++q)
949 {
950 sprintf(ptr, "%d", q); //increment the configname value
951 zc_set_config("recent",configname,(rec_menu_fullpaths[q][0]!='-') ? rec_menu_fullpaths[q] : nullptr);
952 }
953 }
954
955 void update_recent_quest(char const* path)
956 {
957 int32_t ind = -1;
958 for(auto q = 0; q < 10; ++q)
959 {
960 if(!strcmp(path, rec_menu_fullpaths[q]))
961 {
962 ind = q;
963 break;
964 }
965 }
966 if(ind > -1)
967 {
968 for(auto q = ind; q > 0; --q)
969 {
970 strcpy(rec_menu_fullpaths[q], rec_menu_fullpaths[q-1]);
971 strcpy(rec_menu_strs[q], rec_menu_strs[q-1]);
972 }
973 }
974 else
975 {
976 int32_t free_ind = 9; //if none found, override the last index
977 for(auto q = 0; q < 9; ++q)
978 {
979 if(rec_menu_fullpaths[q][0] == '-')
980 {
981 free_ind = q;
982 break;
983 }
984 }
985
986 for(auto q = free_ind; q > 0; --q)
987 {
988 strcpy(rec_menu_fullpaths[q], rec_menu_fullpaths[q-1]);
989 strcpy(rec_menu_strs[q], rec_menu_strs[q-1]);
990 }
991 }
992 char buf[512] = {0};
993 strcpy(rec_menu_fullpaths[0], path);
994 relativize_path(buf, rec_menu_fullpaths[0]);
995 if(strlen(buf) > 62)
996 {
997 buf[60] = buf[61] = buf[62] = '.'; //add "..." as the last 3 characters
998 }
999 strncpy(rec_menu_strs[0], buf, 63);
1000 refresh_recent_menu();
1001 zc_set_config("zquest",last_quest_name,path);
1002 write_recent_quests();
1003 }
1004
1005 void reload_zq_gui()
1006 {
1007 init_custom_fonts();
1008 load_size_poses();
1009 refresh_visible_screens();
1010 update_combobrush();
1011 refresh(rCLEAR|rALL);
1012 }
1013 void change_mapscr_zoom(int delta)
1014 {
1015 int num_screens = Map.getViewSize();
1016 num_screens = std::clamp(num_screens + delta, 1, mapscreen_num_screens_to_draw_max);
1017 Map.setViewSize(num_screens);
1018 std::string qst_cfg_header = qst_cfg_header_from_path(filepath);
1019 zc_set_config(qst_cfg_header.c_str(), "zoom_num_screens", Map.getViewSize());
1020 reload_zq_gui();
1021 }
1022 void toggle_is_compact()
1023 {
1024 is_compact = !is_compact;
1025 zc_set_config("ZQ_GUI","compact_mode",is_compact?1:0);
1026 reload_zq_gui();
1027 }
1028 void toggle_merged_mode()
1029 {
1030 if(is_compact)
1031 {
1032 compact_merged_combopane = !compact_merged_combopane;
1033 zc_set_config("ZQ_GUI","merge_cpane_compact",compact_merged_combopane?1:0);
1034 }
1035 else
1036 {
1037 large_merged_combopane = !large_merged_combopane;
1038 zc_set_config("ZQ_GUI","merge_cpane_large",large_merged_combopane?1:0);
1039 }
1040 reload_zq_gui();
1041 }
1042 void toggle_compact_sqr_mode()
1043 {
1044 compact_square_panels = !compact_square_panels;
1045 zc_set_config("ZQ_GUI","square_panels_compact",compact_square_panels?1:0);
1046 reload_zq_gui();
1047 }
1048 void cycle_compact_sqr(bool down)
1049 {
1050 if(!(is_compact && compact_square_panels))
1051 return;
1052 static const int num_panels = 3;
1053 if(down)
1054 compact_active_panel = (compact_active_panel+1)%num_panels;
1055 else
1056 compact_active_panel = (compact_active_panel-1+num_panels)%num_panels;
1057 reload_zq_gui();
1058 }
1059 void toggle_favzoom_mode()
1060 {
1061 if(is_compact)
1062 {
1063 compact_zoomed_fav = !compact_zoomed_fav;
1064 zc_set_config("ZQ_GUI","zoom_fav_compact",compact_zoomed_fav?1:0);
1065 }
1066 else
1067 {
1068 large_zoomed_fav = !large_zoomed_fav;
1069 zc_set_config("ZQ_GUI","zoom_fav_large",large_zoomed_fav?1:0);
1070 }
1071 reload_zq_gui();
1072 }
1073 void toggle_cmdzoom_mode()
1074 {
1075 if(is_compact)
1076 {
1077 compact_zoomed_cmd = !compact_zoomed_cmd;
1078 zc_set_config("ZQ_GUI","zoom_cmd_compact",compact_zoomed_cmd?1:0);
1079 }
1080 else
1081 {
1082 large_zoomed_cmd = !large_zoomed_cmd;
1083 zc_set_config("ZQ_GUI","zoom_cmd_large",large_zoomed_cmd?1:0);
1084 }
1085 reload_zq_gui();
1086 }
1087
1088 enum
1089 {
1090 MENUID_FILE_SAVE,
1091 MENUID_FILE_SAVEAS,
1092 MENUID_FILE_REVERT,
1093 };
1094
1095
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu file_menu
1096 156 {
1097
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&New", do_NewQuest },
1098
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Open", do_OpenQuest },
1099
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Recent", &recent_menu },
1100
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1101
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Save", onSave, MENUID_FILE_SAVE },
1102
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Save &as...", onSaveAs, MENUID_FILE_SAVEAS },
1103
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Revert", onRevert, MENUID_FILE_REVERT },
1104
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1105
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Import", &import_menu },
1106
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Export", &export_menu },
1107 #ifndef __EMSCRIPTEN__
1108
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1109
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "E&xit", handle_quit },
1110 #endif
1111 };
1112
1113 enum
1114 {
1115 MENUID_MAPS_NEXT,
1116 MENUID_MAPS_PREV,
1117 };
1118
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu maps_menu
1119 72 {
1120
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Goto Map...", onGotoMap },
1121
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Next Map", onIncMap, MENUID_MAPS_NEXT },
1122
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Previous Map", onDecMap, MENUID_MAPS_PREV },
1123
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1124
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "D&elete Map", onDeleteMap },
1125 };
1126
1127
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu misc_menu
1128 132 {
1129
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "S&ubscreens", onEditSubscreens },
1130
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Shop Types", onShopTypes },
1131
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Bottle Types", onBottleTypes },
1132
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Bottle S&hop Types", onBottleShopTypes },
1133
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Info Types", onInfoTypes },
1134
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Warp Rings", onWarpRings },
1135
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Triforce Pieces", onTriPieces },
1136
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&End String", onEndString },
1137
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Item &Drop Sets", onItemDropSets },
1138
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Save Menus", onSaveMenus },
1139 };
1140
1141
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu spr_menu
1142 48 {
1143
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Sprite Data", onCustomWpns },
1144
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Hero", onCustomHero },
1145
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Misc Sprites", onMiscSprites },
1146 };
1147
1148
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 NewMenu colors_menu
1149 48 {
1150
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Main ", onColors_Main },
1151
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Levels ", onColors_Levels },
1152
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Sprites ", onColors_Sprites },
1153 };
1154
1155
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu defs_menu
1156 108 {
1157
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palettes", onDefault_Pals },
1158
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tiles", onDefault_Tiles },
1159
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combos", onDefault_Combos },
1160
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Items", onDefault_Items },
1161
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onDefault_Guys },
1162
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Sprite Data", onDefault_Weapons },
1163
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map Styles", onDefault_MapStyles },
1164
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "SF&X Data", onDefault_SFX },
1165 };
1166
1167 int32_t onEditComboAlias();
1168 int32_t onEditComboPool();
1169 int32_t onEditAutoCombo();
1170
1171
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu graphics_menu
1172 144 {
1173
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palettes ", &colors_menu },
1174
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Sprites ", &spr_menu },
1175
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combos", onCombos },
1176
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tiles", onTiles },
1177
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Game icons", onIcons },
1178
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Misc co&lors", onMiscColors },
1179
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map styles", onMapStyles },
1180
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Door Combo Sets", onDoorCombos },
1181
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo &Aliases", [](){call_alias_pages(); return D_O_K;} },
1182
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo Pools", [](){call_cpool_pages(); return D_O_K;} },
1183
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Auto Combos", [](){call_autoc_pages(); return D_O_K;} },
1184 };
1185
1186
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu audio_menu
1187 60 {
1188
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "SF&X Data", onSelectSFX },
1189
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Music", onMusic },
1190
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "M&IDIs", onMidis },
1191
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Mis&c SFX", onMiscSFX },
1192 };
1193
1194 void set_rules(byte* newrules);
1195
1196 void call_testqst_dialog();
1197 int32_t onTestQst()
1198 {
1199 call_testqst_dialog();
1200 return D_O_K;
1201 }
1202
1203 int32_t onRulesDlg()
1204 {
1205 call_qr_dialog(21, set_rules);
1206 return D_O_K;
1207 }
1208
1209 int32_t onRulesSearch()
1210 {
1211 call_qrsearch_dialog(set_rules);
1212 return D_O_K;
1213 }
1214
1215 int32_t onZScriptSettings()
1216 {
1217 ScriptRulesDialog(quest_rules, 17, [](byte* newrules)
1218 {
1219 mark_save_dirty();
1220 memcpy(quest_rules, newrules, QR_SZ);
1221 unpack_qrs();
1222 }).show();
1223 return D_O_K;
1224 }
1225
1226 void call_zinf_dlg();
1227 int32_t onZInfo()
1228 {
1229 call_zinf_dlg();
1230 return D_O_K;
1231 }
1232
1233
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu quest_menu
1234 204 {
1235
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Options ", onRulesDlg },
1236
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Test", onTestQst },
1237
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Items", onCustomItems },
1238
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onCustomEnemies },
1239
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Hero", onCustomHero },
1240
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Strings", onStrings },
1241
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onDmaps },
1242
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map Settings", onMaps },
1243
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "I&nit Data", onInit },
1244
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Misc D&ata ", &misc_menu },
1245
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&ZInfo", onZInfo },
1246
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1247
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Graphics ", &graphics_menu },
1248
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "A&udio ", &audio_menu },
1249
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1250
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "De&faults ", &defs_menu },
1251 };
1252
1253
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu paste_menu
1254 36 {
1255
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste &To All", onPasteToAll },
1256
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste &All To All", onPasteAllToAll },
1257 };
1258
1259
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu paste_item_menu
1260 156 {
1261
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Undercombo", onPasteUnderCombo },
1262
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Secret Combos", onPasteSecretCombos },
1263
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Freeform Combos", onPasteFFCombos },
1264
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Screen &Data", onPasteScreenData },
1265
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Warps", onPasteWarps },
1266
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Warp &Return", onPasteWarpLocations },
1267
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onPasteEnemies },
1268
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Room &Type Data", onPasteRoom },
1269
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Guy/String", onPasteGuy },
1270
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Doo&rs", onPasteDoors },
1271
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Layers", onPasteLayers },
1272
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palette", onPastePalette },
1273 };
1274
1275 enum
1276 {
1277 MENUID_EDIT_UNDO,
1278 MENUID_EDIT_REDO,
1279 MENUID_EDIT_COPY,
1280 MENUID_EDIT_PASTE,
1281 MENUID_EDIT_PASTEALL,
1282 MENUID_EDIT_ADVPASTE,
1283 MENUID_EDIT_SPECPASTE,
1284 MENUID_EDIT_DELETE,
1285 };
1286
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu edit_menu
1287 132 {
1288
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Undo", onUndo, MENUID_EDIT_UNDO },
1289
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Redo", onRedo, MENUID_EDIT_REDO },
1290
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Copy", onCopy, MENUID_EDIT_COPY },
1291
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Paste", onPaste, MENUID_EDIT_PASTE },
1292
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste A&ll", onPasteAll, MENUID_EDIT_PASTEALL },
1293
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Adv. Paste ", &paste_menu, MENUID_EDIT_ADVPASTE },
1294
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste &Spec. ", &paste_item_menu, MENUID_EDIT_SPECPASTE },
1295
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Delete", onDelete, MENUID_EDIT_DELETE },
1296
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1297
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Maps ", &maps_menu },
1298 };
1299
1300
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu drawing_mode_menu
1301 60 {
1302
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Normal", onDrawingModeNormal, dm_normal },
1303
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Alias", onDrawingModeAlias, dm_alias },
1304
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Pool", onDrawingModePool, dm_cpool },
1305
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Auto Combo", onDrawingModeAuto, dm_auto },
1306 };
1307
1308
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu integrity_check_menu
1309 48 {
1310
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&All ", onIntegrityCheckAll },
1311
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Screens ", onIntegrityCheckRooms },
1312
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Warps ", onIntegrityCheckWarps },
1313 };
1314
1315
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu quest_reports_menu
1316 108 {
1317
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Bugged Next-> Combo Locations", onBuggedNextComboLocationReport },
1318
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Locations", onComboLocationReport },
1319
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Type Locations", onComboTypeLocationReport },
1320
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemy Locations", onEnemyLocationReport },
1321
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Item Locations", onItemLocationReport },
1322
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Script Locations", onScriptLocationReport },
1323
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&What Links Here", onWhatWarpsReport },
1324
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "In&tegrity Check ", &integrity_check_menu },
1325 };
1326
1327 int32_t onPalFix();
1328 int32_t onPitFix();
1329 int32_t onStrFix()
1330 {
1331 if(get_qr(qr_OLD_STRING_EDITOR_MARGINS))
1332 {
1333 if (alert_confirm("Fix: Old Margins",
1334 "Fixing margins may cause strings that used to spill outside the textbox"
1335 " to instead be cut off. Are you sure?"))
1336 {
1337 set_qr(qr_OLD_STRING_EDITOR_MARGINS, 0);
1338 mark_save_dirty();
1339 }
1340 }
1341 if(get_qr(qr_STRING_FRAME_OLD_WIDTH_HEIGHT))
1342 {
1343 if (alert_confirm("Fix: Old Frame Size",
1344 "This will fix the frame size of all strings. No visual changes should occur,"
1345 " as the string width/height will be fixed, but the compat QR will also be unchecked."))
1346 {
1347 for(auto q = 0; q < msg_count; ++q)
1348 {
1349 MsgStrings[q].w += 16;
1350 MsgStrings[q].h += 16;
1351 }
1352 set_qr(qr_STRING_FRAME_OLD_WIDTH_HEIGHT, 0);
1353 mark_save_dirty();
1354 }
1355 }
1356 return D_O_K;
1357 }
1358
1359 int32_t onRemoveOldArrivalSquare();
1360 enum
1361 {
1362 MENUID_FIXTOOL_OLDSTRING,
1363 };
1364
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu fixtools_menu
1365 96 {
1366
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Color Set Fix", onCSetFix },
1367
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Liquid Solidity Fix", onWaterSolidity },
1368
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Effect Square Fix", onEffectFix },
1369
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Level Palette Fix", onPalFix },
1370
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Pit and Liquid Damage Fix", onPitFix },
1371
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Old Strings Fix", onStrFix, MENUID_FIXTOOL_OLDSTRING },
1372
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Green Arrival Square Fix", onRemoveOldArrivalSquare },
1373 };
1374
1375
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu tool_menu
1376 132 {
1377
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo &Flags", onFlags, nullopt, MFL_EXIT_PRE_PROC },
1378
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fix &Tools ", &fixtools_menu },
1379
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&NES Dungeon Template", onTemplate },
1380
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Apply Template to All", onReTemplate },
1381
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1382
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Preview Mode", onPreviewMode },
1383
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Drawing &Mode ", &drawing_mode_menu },
1384
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1385
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&List Combos Used", onUsedCombos },
1386
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Quest Reports ", &quest_reports_menu },
1387 };
1388
1389 int32_t onLayer3BG()
1390 {
1391 ViewLayer3BG = ViewLayer3BG ? 0 : 1;
1392 zc_set_config("zquest","layer3_bg",ViewLayer3BG);
1393 return D_O_K;
1394 }
1395 int32_t onLayer2BG()
1396 {
1397 ViewLayer2BG = ViewLayer2BG ? 0 : 1;
1398 zc_set_config("zquest","layer2_bg",ViewLayer2BG);
1399 return D_O_K;
1400 }
1401 int onGridToggle();
1402 int onToggleHighQualityScreenRendering();
1403 enum
1404 {
1405 MENUID_VIEW_WALKABILITY,
1406 MENUID_VIEW_FLAGS,
1407 MENUID_VIEW_CSET,
1408 MENUID_VIEW_TYPES,
1409 MENUID_VIEW_INFO,
1410 MENUID_VIEW_SQUARES,
1411 MENUID_VIEW_FFCS,
1412 MENUID_VIEW_SCRIPTNAMES,
1413 MENUID_VIEW_GRID,
1414 MENUID_VIEW_SCREENGRID,
1415 MENUID_VIEW_REGIONGRID,
1416 MENUID_VIEW_CURSCROUTLINE,
1417 MENUID_VIEW_DARKNESS,
1418 MENUID_VIEW_L2BG,
1419 MENUID_VIEW_L3BG,
1420 MENUID_VIEW_LAYERHIGHLIGHT,
1421 MENUID_VIEW_HIGH_QUALITY_SCREEN_RENDERING,
1422 };
1423
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 NewMenu view_menu
1424 264 {
1425
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "View &Map...", onViewMap },
1426
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "View &Palette", onShowPal },
1427
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1428
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Walkability", onShowWalkability, MENUID_VIEW_WALKABILITY },
1429
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Flags", onShowFlags, MENUID_VIEW_FLAGS },
1430
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &CSets", onShowCSet, MENUID_VIEW_CSET },
1431
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Types", onShowCType, MENUID_VIEW_TYPES },
1432
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1433
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Screen &Info", onToggleShowInfo, MENUID_VIEW_INFO },
1434
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Squares", onToggleShowSquares, MENUID_VIEW_SQUARES },
1435
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show FFCs", onToggleShowFFCs, MENUID_VIEW_FFCS },
1436
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Script &Names", onToggleShowScripts, MENUID_VIEW_SCRIPTNAMES },
1437
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Grid", onGridToggle, MENUID_VIEW_GRID },
1438
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Screen G&rid", onToggleScreenGrid, MENUID_VIEW_SCREENGRID },
1439
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Region Grid", onToggleRegionGrid, MENUID_VIEW_REGIONGRID },
1440
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Current Screen Outline", onToggleCurrentScreenOutline, MENUID_VIEW_CURSCROUTLINE },
1441
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Darkness", onShowDarkness, MENUID_VIEW_DARKNESS },
1442
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Layer 2 is Background", onLayer2BG, MENUID_VIEW_L2BG },
1443
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Layer 3 is Background", onLayer3BG, MENUID_VIEW_L3BG },
1444
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Highlight Current Layer", onToggleHighlightLayer, MENUID_VIEW_LAYERHIGHLIGHT },
1445
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "High &Quality Screen Rendering", onToggleHighQualityScreenRendering, MENUID_VIEW_HIGH_QUALITY_SCREEN_RENDERING },
1446 };
1447
1448 11 void set_rules(byte* newrules)
1449 {
1450 11 mark_save_dirty();
1451
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(newrules != quest_rules)
1452 memcpy(quest_rules, newrules, QR_SZ);
1453 11 unpack_qrs();
1454
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 if(!get_qr(qr_ALLOW_EDITING_COMBO_0))
1455 {
1456 2 combobuf[0].walk = 0xF0;
1457 2 combobuf[0].type = 0;
1458 2 combobuf[0].flag = 0;
1459 2 }
1460
1461 // For 2.50.0 and 2.50.1
1462
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 if(get_qr(qr_VERYFASTSCROLLING))
1463 2 set_qr(qr_FASTDNGN, 1);
1464 11 }
1465
1466 int32_t onSelectFFCombo();
1467
1468 void onScreenNotes()
1469 {
1470 edit_screen_notes(Map.CurrScr(), Map.getCurrMap(), Map.getCurrScr());
1471 }
1472
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu data_menu
1473 216 {
1474
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Screen Data", onScrData },
1475
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Freeform Combos", onSelectFFCombo },
1476
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "La&yers", onLayers },
1477
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tile Warp", onTileWarp },
1478
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Side &Warp", onSideWarp },
1479
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Secret &Combos", onSecretCombo },
1480
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Under Combo", onUnderCombo },
1481
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Doors", onDoors },
1482
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Maze Path", onPath },
1483
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1484
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Item", onItem },
1485
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onEnemies },
1486
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palette", onScreenPalette },
1487
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1488
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Room Data", onRoom },
1489
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Notes", onScreenNotes },
1490
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Browse Notes", browse_screen_notes },
1491 };
1492
1493
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu tunes_menu
1494 252 {
1495
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "ZC Forever", playZCForever },
1496
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Wind Fish", playTune1 },
1497
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Overworld", playTune2 },
1498
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Hyrule Castle", playTune3 },
1499
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Lost Woods", playTune4 },
1500
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Great Sea", playTune5 },
1501
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "East Hyrule", playTune6 },
1502
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Dancing Dragon", playTune7 },
1503
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Stone Tower", playTune8 },
1504
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Villages", playTune9 },
1505
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Swamp + Desert", playTune10 },
1506
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Outset Island", playTune11 },
1507
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Kakariko Village", playTune12 },
1508
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Clock Town", playTune13 },
1509
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Temple", playTune14 },
1510
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Dark World", playTune15 },
1511
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Dragon Roost", playTune16 },
1512
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Horse Race", playTune17 },
1513
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Credits", playTune18 },
1514
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Zelda's Lullaby", playTune19 },
1515 };
1516
1517 enum
1518 {
1519 MENUID_MEDIA_TUNES,
1520 MENUID_MEDIA_PLAYMUSIC,
1521 MENUID_MEDIA_CHANGETRACK,
1522 };
1523
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu media_menu
1524 60 {
1525
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Ambient Music ", &tunes_menu, MENUID_MEDIA_TUNES },
1526
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Play music", playMusic, MENUID_MEDIA_PLAYMUSIC },
1527
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Change track", changeTrack, MENUID_MEDIA_CHANGETRACK },
1528
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Stop tunes", stopMusic },
1529 };
1530
1531 enum
1532 {
1533 MENUID_ETC_VIDMODE,
1534 MENUID_ETC_FULLSCREEN,
1535 MENUID_ETC_DEBUG_CONSOLE,
1536 };
1537
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu etc_menu
1538 192 {
1539
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Help", &zq_help_menu },
1540
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&About", onAbout },
1541
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Video Mode", onZQVidMode, MENUID_ETC_VIDMODE },
1542
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Options...", onOptions },
1543
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Hotkeys...", do_zq_hotkey_dialog },
1544
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&List Hotkeys...", do_zq_list_hotkeys_dialog },
1545
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Fullscreen", onFullScreen, MENUID_ETC_FULLSCREEN },
1546
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1547
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&View Pic...", onViewPic },
1548
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Media", &media_menu },
1549
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1550
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Debug Console", toggleConsole, MENUID_ETC_DEBUG_CONSOLE },
1551
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Clear Quest Filepath", onClearQuestFilepath },
1552
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Take ZQ Snapshot", onMenuSnapshot },
1553
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Take &Screen Snapshot", onMapscrSnapshot },
1554 };
1555
1556
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu zscript_menu
1557 60 {
1558
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Compile &ZScript...", onCompileScript },
1559
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1560
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Compiler Settings", onZScriptCompilerSettings },
1561
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Quest Script Settings", onZScriptSettings },
1562 };
1563
1564 void set_console_state()
1565 {
1566 etc_menu.select_uid(MENUID_ETC_DEBUG_CONSOLE, console_is_open);
1567 }
1568
1569
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 TopMenu the_menu
1570 108 {
1571
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&File", &file_menu },
1572
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Quest", &quest_menu },
1573
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Edit", &edit_menu },
1574
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&View", &view_menu },
1575
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tools", &tool_menu },
1576
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Screen", &data_menu },
1577
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&ZScript", &zscript_menu },
1578
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Et&C", &etc_menu },
1579 };
1580
1581 void rebuild_trans_table();
1582 int32_t launchPicViewer(BITMAP **pictoview, PALETTE pal,
1583 int32_t &px2, int32_t &py2, double &scale, bool isviewingmap, bool skipmenu = false);
1584
1585 int32_t onResetTransparency()
1586 {
1587 restore_mouse();
1588 rebuild_trans_table();
1589 displayinfo("Notice","Translucency Table Rebuilt");
1590
1591 refresh(rALL);
1592 return D_O_K;
1593 }
1594
1595 int32_t onFullScreen()
1596 {
1597 get_palette(RAMpal);
1598 bool windowed=is_windowed_mode()!=0;
1599 all_toggle_fullscreen(windowed);
1600
1601 gui_mouse_focus=0;
1602 gui_bg_color=jwin_pal[jcBOX];
1603 gui_fg_color=jwin_pal[jcBOXFG];
1604 MouseSprite::set(ZQM_NORMAL);
1605 zc_set_palette(RAMpal);
1606 position_mouse(zq_screen_w/2,zq_screen_h/2);
1607 set_display_switch_mode(SWITCH_BACKGROUND);
1608 set_display_switch_callback(SWITCH_OUT, switch_out);
1609 set_display_switch_callback(SWITCH_IN, switch_in);
1610 zc_set_config("zquest","fullscreen", is_windowed_mode() ? 0 : 1);
1611 return D_REDRAW;
1612 }
1613
1614 int32_t onEnter()
1615 {
1616 if(key[KEY_ALT]||key[KEY_ALTGR])
1617 {
1618 return onFullScreen();
1619 }
1620
1621 return D_O_K;
1622 }
1623
1624 //PROC, x, y, w, h, fg, bg, key, flags, d1, d2, *dp, *dp2, *dp3
1625
1626 //*text, (*proc), *child, flags, *dp
1627
1628 void run_zq_frame();
1629 int32_t d_nbmenu_proc(int32_t msg,DIALOG *d,int32_t c);
1630
1631
1632 /*int32_t onY()
1633 {
1634 return D_O_K;
1635 }*/
1636
1637 int32_t onToggleGrid(bool color)
1638 {
1639 if(color)
1640 {
1641 GridColor=(GridColor+8)%16;
1642 zc_set_config("zquest", "grid_color", GridColor);
1643 }
1644 else
1645 {
1646 ShowGrid=!ShowGrid;
1647 zc_set_config("zquest","show_grid",ShowGrid);
1648 }
1649
1650 return D_O_K;
1651 }
1652
1653 int onGridToggle()
1654 {
1655 return onToggleGrid(CHECK_CTRL_CMD);
1656 }
1657
1658 int onToggleHighQualityScreenRendering()
1659 {
1660 HighQualityScreenRendering = !HighQualityScreenRendering;
1661 zc_set_config("zquest","high_quality_screen_rendering",HighQualityScreenRendering);
1662
1663 if (!HighQualityScreenRendering)
1664 {
1665 mapview_get_rti()->remove();
1666 }
1667
1668 return D_O_K;
1669 }
1670
1671 int32_t onToggleScreenGrid()
1672 {
1673 ShowScreenGrid=!ShowScreenGrid;
1674 zc_set_config("zquest","show_screen_grid",ShowScreenGrid);
1675 return D_O_K;
1676 }
1677
1678 int32_t onToggleRegionGrid()
1679 {
1680 ShowRegionGrid=!ShowRegionGrid;
1681 zc_set_config("zquest","show_region_grid",ShowRegionGrid);
1682 return D_O_K;
1683 }
1684
1685 int32_t onToggleCurrentScreenOutline()
1686 {
1687 ShowCurScreenOutline=!ShowCurScreenOutline;
1688 zc_set_config("zquest","show_current_screen_outline",ShowCurScreenOutline);
1689 return D_O_K;
1690 }
1691
1692 int32_t onToggleShowScripts()
1693 {
1694 ShowFFScripts=!ShowFFScripts;
1695 zc_set_config("zquest","showffscripts",ShowFFScripts);
1696 return D_O_K;
1697 }
1698
1699 int32_t onToggleShowFFCs()
1700 {
1701 ShowFFCs=!ShowFFCs;
1702 zc_set_config("zquest","showffcs",ShowFFCs);
1703 return D_O_K;
1704 }
1705
1706 int32_t onToggleShowSquares()
1707 {
1708 ShowSquares=!ShowSquares;
1709 zc_set_config("zquest","showsquares",ShowSquares);
1710 return D_O_K;
1711 }
1712
1713 int32_t onToggleShowInfo()
1714 {
1715 ShowInfo=!ShowInfo;
1716 zc_set_config("zquest","showinfo",ShowInfo);
1717 return D_O_K;
1718 }
1719
1720 int32_t onToggleHighlightLayer()
1721 {
1722 ActiveLayerHighlight = ActiveLayerHighlight ? 0 : 1;
1723 zc_set_config("zquest","hl_active_lyr",ActiveLayerHighlight);
1724 return D_O_K;
1725 }
1726
1727 int onKeySlash()
1728 {
1729 if(key[KEY_LSHIFT] || key[KEY_RSHIFT])
1730 {
1731 onAbout();
1732 }
1733 return D_O_K;
1734 }
1735
1736 int onAKey()
1737 {
1738 if(prv_mode)
1739 Map.set_prvadvance(1);
1740 return D_O_K;
1741 }
1742
1743 int onReloadPreview()
1744 {
1745 if(prv_mode)
1746 {
1747 Map.set_prvscr(Map.get_prv_map(), Map.get_prv_scr());
1748 Map.set_prvcmb(0);
1749 }
1750 return D_O_K;
1751 }
1752 int onSecretsPreview()
1753 {
1754 if(prv_mode)
1755 {
1756 Map.prv_secrets(false);
1757 refresh(rALL);
1758 }
1759 return D_O_K;
1760 }
1761
1762 int onSKey()
1763 {
1764 if(CHECK_CTRL_CMD)
1765 {
1766 if(key[KEY_LSHIFT] || key[KEY_RSHIFT])
1767 {
1768 onSaveAs();
1769 }
1770 else
1771 {
1772 if(!saved)
1773 onSave();
1774 }
1775 }
1776 else if(prv_mode)
1777 {
1778 Map.prv_secrets(false);
1779 refresh(rALL);
1780 }
1781 else onStrings();
1782 return D_O_K;
1783 }
1784 int onSetNewLayer(int newlayer)
1785 {
1786 CurrentLayer = newlayer;
1787 refresh(rALL);
1788 return D_O_K;
1789 }
1790 void lpal_dsa()
1791 {
1792 info_dsa("Level Palette Shortcuts",
1793 "You currently have level palette shortcuts disabled."
1794 " These can be re-enabled in 'Etc->Options', on the toggle 'Disable Level Palette Shortcuts'.",
1795 "dsa_lpal");
1796 }
1797 int onScreenLPal(int lpal)
1798 {
1799 if(DisableLPalShortcuts)
1800 {
1801 lpal_dsa();
1802 return D_O_K;
1803 }
1804 mark_save_dirty();
1805 Map.setcolor(lpal);
1806 refresh(rSCRMAP);
1807 return D_O_K;
1808 }
1809
1810 int32_t onPressEsc()
1811 {
1812 if(zoomed_minimap)
1813 mmap_set_zoom(false);
1814 else return onExit();
1815 return D_O_K;
1816 }
1817
1818 static DIALOG dialogs[] =
1819 {
1820 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
1821 { d_nbmenu_proc, 0, 0, 0, 13, 0, 0, 0, D_USER, 0, 0, (void *) &the_menu, NULL, NULL },
1822 { d_zq_hotkey_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
1823
1824 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *) onHelp, NULL, NULL },
1825 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_ESC, 0, (void *) onPressEsc, NULL, NULL },
1826 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, (void *) onUsedCombos, NULL, NULL },
1827 { d_vsync_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
1828 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
1829 };
1830
1831
1832 int32_t onDecColour()
1833 {
1834 if ( CHECK_CTRL_CMD )
1835 {
1836 return onDecScrPal16();
1837 }
1838
1839 else if ( key[KEY_LSHIFT] || key[KEY_RSHIFT] )
1840 {
1841 return onDecScrPal();
1842 }
1843
1844 else
1845 {
1846 return onDecreaseCSet();
1847 }
1848 }
1849
1850 int32_t onIncColour()
1851 {
1852
1853 if ( CHECK_CTRL_CMD )
1854 {
1855 return onIncScrPal16();
1856 }
1857
1858 else if ( key[KEY_LSHIFT] || key[KEY_RSHIFT] )
1859 {
1860 return onIncScrPal();
1861 }
1862
1863 else
1864 {
1865 return onIncreaseCSet();
1866 }
1867 }
1868
1869 static DIALOG save_tiles_dlg[] =
1870 {
1871 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
1872
1873
1874 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save Tile Pack", NULL, NULL },
1875 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
1876 //for future tabs
1877 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
1878 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
1879 //4
1880 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
1881 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
1882 //6
1883 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
1884 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
1885 //8
1886 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
1887 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
1888 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
1889 };
1890
1891
1892 void savesometiles(const char *prompt,int32_t initialval)
1893 {
1894
1895 char firsttile[8], tilecount[8];
1896 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
1897 sprintf(firsttile,"%d",0);
1898 sprintf(tilecount,"%d",1);
1899 //int32_t ret;
1900
1901
1902
1903 save_tiles_dlg[0].dp2 = get_zc_font(font_lfont);
1904
1905 sprintf(firsttile,"%d",0);
1906 sprintf(tilecount,"%d",1);
1907
1908 save_tiles_dlg[5].dp = firsttile;
1909 save_tiles_dlg[7].dp = tilecount;
1910
1911 large_dialog(save_tiles_dlg);
1912
1913 int32_t ret = do_zqdialog(save_tiles_dlg,-1);
1914 jwin_center_dialog(save_tiles_dlg);
1915
1916 if(ret == 8)
1917 {
1918 first_tile_id = vbound(atoi(firsttile), 0, NEWMAXTILES);
1919 the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
1920 if(prompt_for_new_file_compat("Save ZTILE(.ztile)", "ztile", NULL,datapath,false))
1921 {
1922 char name[PATH_MAX];
1923 extract_name(temppath,name,FILENAMEALL);
1924 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
1925 if(f)
1926 {
1927 writetilefile(f,first_tile_id,the_tile_count);
1928 pack_fclose(f);
1929 displayinfo("Success!",fmt::format("Saved {}",name));
1930 }
1931 }
1932 }
1933 }
1934
1935 static DIALOG read_tiles_dlg[] =
1936 {
1937 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
1938
1939
1940 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Load Tilepack To:", NULL, NULL },
1941 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
1942 //for future tabs
1943 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
1944 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
1945 //4
1946 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Starting at:", NULL, NULL },
1947 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
1948 //6
1949 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
1950 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
1951 //8
1952 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
1953 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
1954 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
1955 };
1956
1957
1958 void writesometiles_to(const char *prompt,int32_t initialval)
1959 {
1960
1961 char firsttile[8];;
1962 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
1963 sprintf(firsttile,"%d",0);
1964 //int32_t ret;
1965
1966
1967
1968 read_tiles_dlg[0].dp2 = get_zc_font(font_lfont);
1969
1970 sprintf(firsttile,"%d",0);
1971 //sprintf(tilecount,"%d",1);
1972
1973 read_tiles_dlg[5].dp = firsttile;
1974
1975 large_dialog(read_tiles_dlg);
1976
1977 int32_t ret = do_zqdialog(read_tiles_dlg,-1);
1978 jwin_center_dialog(read_tiles_dlg);
1979
1980 if(ret == 8)
1981 {
1982 first_tile_id = vbound(atoi(firsttile), 0, NEWMAXTILES);
1983 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
1984 if(prompt_for_existing_file_compat("Load ZTILE(.ztile)", "ztile", NULL,datapath,false))
1985 {
1986
1987 char name[256];
1988 extract_name(temppath,name,FILENAMEALL);
1989 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
1990 if(f)
1991 {
1992
1993 if (!readtilefile_to_location(f,first_tile_id))
1994 {
1995 al_trace("Could not read from .ztile packfile %s\n", name);
1996 displayinfo("ZTILE File: Error","Could not load the specified Tile.");
1997 }
1998 else
1999 {
2000 displayinfo("ZTILE File: Success!","Loaded the source tiles to your tile sheets!");
2001 }
2002 pack_fclose(f);
2003 }
2004 }
2005 }
2006 }
2007
2008
2009 static DIALOG save_combofiles_dlg[] =
2010 {
2011 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2012
2013
2014 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save Combo Pack", NULL, NULL },
2015 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2016 //for future tabs
2017 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2018 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2019 //4
2020 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
2021 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2022 //6
2023 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2024 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2025 //8
2026 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
2027 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2028 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2029 };
2030
2031
2032 void savesomecombos(const char *prompt,int32_t initialval)
2033 {
2034
2035 char firsttile[8], tilecount[8];
2036 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2037 sprintf(firsttile,"%d",0);
2038 sprintf(tilecount,"%d",1);
2039 //int32_t ret;
2040
2041
2042
2043 save_combofiles_dlg[0].dp2 = get_zc_font(font_lfont);
2044
2045 sprintf(firsttile,"%d",0);
2046 sprintf(tilecount,"%d",1);
2047
2048 save_combofiles_dlg[5].dp = firsttile;
2049 save_combofiles_dlg[7].dp = tilecount;
2050
2051 large_dialog(save_combofiles_dlg);
2052
2053 int32_t ret = do_zqdialog(save_combofiles_dlg,-1);
2054 jwin_center_dialog(save_combofiles_dlg);
2055
2056 if(ret == 8)
2057 {
2058 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOS-1));
2059 the_tile_count = vbound(atoi(tilecount), 1, (MAXCOMBOS-1)-first_tile_id);
2060 if(prompt_for_new_file_compat("Save ZCOMBO(.zcombo)", "zcombo", NULL,datapath,false))
2061 {
2062 char name[PATH_MAX];
2063 extract_name(temppath,name,FILENAMEALL);
2064 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
2065 if(f)
2066 {
2067 writecombofile(f,first_tile_id,the_tile_count);
2068 pack_fclose(f);
2069 displayinfo("Success!",fmt::format("Saved {}",name));
2070 }
2071 }
2072 }
2073 }
2074
2075
2076 static DIALOG load_comboset_dlg[] =
2077 {
2078 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2079
2080
2081 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Combo Set (Range)", NULL, NULL },
2082 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2083 //for future tabs
2084 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2085 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2086 //4
2087 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First:", NULL, NULL },
2088 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2089 //6
2090 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2091 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2092 //8
2093 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2094 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2095 { jwin_check_proc, 10, 46, 95, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Don't Overwrite", NULL, NULL },
2096
2097 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2098 };
2099
2100 void writesomecombos(const char *prompt,int32_t initialval)
2101 {
2102
2103 char firsttile[8];
2104 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2105 sprintf(firsttile,"%d",0);
2106 //int32_t ret;
2107
2108
2109
2110 load_comboset_dlg[0].dp2 = get_zc_font(font_lfont);
2111
2112 sprintf(firsttile,"%d",0);
2113 //sprintf(tilecount,"%d",1);
2114
2115 load_comboset_dlg[5].dp = firsttile;
2116
2117 byte nooverwrite = 0;
2118
2119
2120 large_dialog(load_comboset_dlg);
2121
2122 int32_t ret = do_zqdialog(load_comboset_dlg,-1);
2123 jwin_center_dialog(load_comboset_dlg);
2124
2125 if(ret == 8)
2126 {
2127 if (load_comboset_dlg[10].flags & D_SELECTED) nooverwrite = 1;
2128
2129 al_trace("Nooverwrite is: %d\n", nooverwrite);
2130 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOS-1));
2131 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
2132 if(prompt_for_existing_file_compat("Load ZCOMBO(.zcombo)", "zcombo", NULL,datapath,false))
2133 {
2134 char name[256];
2135 extract_name(temppath,name,FILENAMEALL);
2136 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2137 if(f)
2138 {
2139
2140 if (!readcombofile(f,first_tile_id,nooverwrite))
2141 {
2142 al_trace("Could not read from .zcombo packfile %s\n", name);
2143 displayinfo("ZCOMBO File: Error","Could not load the specified combos.");
2144 }
2145 else
2146 {
2147 displayinfo("ZCOMBO File: Success!","Loaded the source combos to your combo pages!");
2148 mark_save_dirty();
2149 }
2150 pack_fclose(f);
2151 }
2152
2153 }
2154 }
2155 }
2156
2157 static DIALOG load_combopack_dlg[] =
2158 {
2159 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2160
2161
2162 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Import Full Combo Package 1:1", NULL, NULL },
2163 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2164 //for future tabs
2165 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2166 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2167 //4
2168 { d_dummy_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Starting at:", NULL, NULL },
2169 { d_dummy_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2170 //6
2171 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2172 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2173 //8
2174 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2175 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2176 { jwin_check_proc, 10, 42, 95, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Don't Overwrite", NULL, NULL },
2177
2178 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2179 };
2180
2181 void loadcombopack(const char *prompt,int32_t initialval)
2182 {
2183
2184 char firsttile[8];
2185 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2186 sprintf(firsttile,"%d",0);
2187 //int32_t ret;
2188
2189
2190
2191 load_combopack_dlg[0].dp2 = get_zc_font(font_lfont);
2192
2193 sprintf(firsttile,"%d",0);
2194 //sprintf(tilecount,"%d",1);
2195
2196 load_combopack_dlg[5].dp = firsttile;
2197
2198 byte nooverwrite = 0;
2199
2200
2201 large_dialog(load_combopack_dlg);
2202
2203 int32_t ret = do_zqdialog(load_combopack_dlg,-1);
2204 jwin_center_dialog(load_combopack_dlg);
2205
2206 if(ret == 8)
2207 {
2208 if (load_combopack_dlg[10].flags & D_SELECTED) nooverwrite = 1;
2209
2210 al_trace("Nooverwrite is: %d\n", nooverwrite);
2211 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOS-1));
2212 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
2213 if(prompt_for_existing_file_compat("Load ZCOMBO(.zcombo)", "zcombo", NULL,datapath,false))
2214 {
2215 char name[256];
2216 extract_name(temppath,name,FILENAMEALL);
2217 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2218 if(f)
2219 {
2220 //need dialogue here
2221 if (!readcombofile(f,0,nooverwrite))
2222 {
2223 al_trace("Could not read from .zcombo packfile %s\n", name);
2224 displayinfo("ZCOMBO File: Error","Could not load the specified Tile.");
2225 }
2226 else
2227 {
2228 displayinfo("ZCOMBO File: Success!","Loaded the source combos to your combo pages!");
2229 mark_save_dirty();
2230 }
2231 }
2232
2233 pack_fclose(f);
2234 }
2235 }
2236 }
2237
2238
2239 static DIALOG read_combopack_dlg[] =
2240 {
2241 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2242
2243
2244 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Load Combos (Specific Dest)", NULL, NULL },
2245 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2246 //for future tabs
2247 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2248 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2249 //4
2250 { jwin_text_proc, 10, 24, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Starting at:", NULL, NULL },
2251 { jwin_edit_proc, 55, 22, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2252 //6
2253 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2254 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2255 //8
2256 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2257 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2258 //10
2259 { jwin_check_proc, 10, 58, 95, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Don't Overwrite", NULL, NULL },
2260 //11
2261 { jwin_text_proc, 10, 42, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Skip:", NULL, NULL },
2262 //12
2263 { jwin_edit_proc, 55, 40, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2264
2265 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2266 };
2267
2268
2269
2270 void writesomecombos_to(const char *prompt,int32_t initialval)
2271 {
2272
2273 char firsttile[8];
2274 char skiptile[8];
2275 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2276 sprintf(firsttile,"%d",0);
2277 //int32_t ret;
2278
2279
2280
2281 read_combopack_dlg[0].dp2 = get_zc_font(font_lfont);
2282
2283 sprintf(skiptile,"%d",0);
2284 //sprintf(tilecount,"%d",1);
2285
2286 read_combopack_dlg[5].dp = firsttile;
2287
2288 byte nooverwrite = 0;
2289 int32_t skipover = 0;
2290
2291 sprintf(skiptile,"%d",0);
2292 //sprintf(tilecount,"%d",1);
2293
2294 read_combopack_dlg[12].dp = skiptile;
2295
2296 large_dialog(read_combopack_dlg);
2297
2298 int32_t ret = do_zqdialog(read_combopack_dlg,-1);
2299 jwin_center_dialog(read_combopack_dlg);
2300
2301 if(ret == 8)
2302 {
2303 if (read_combopack_dlg[10].flags & D_SELECTED) nooverwrite = 1;
2304
2305 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOS-1));
2306 skipover = vbound(atoi(skiptile), 0, (MAXCOMBOS-1));
2307 al_trace("skipover is: %d\n", skipover);
2308 //skipover = vbound(skipover, 0, (MAXCOMBOS-1-skipover));
2309 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
2310 if(prompt_for_existing_file_compat("Load ZCOMBO(.zcombo)", "zcombo", NULL,datapath,false))
2311 {
2312 char name[256];
2313 extract_name(temppath,name,FILENAMEALL);
2314 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2315 if(f)
2316 {
2317
2318 if (!readcombofile_to_location(f,first_tile_id,nooverwrite, skipover))
2319 {
2320 al_trace("Could not read from .zcombo packfile %s\n", name);
2321 displayinfo("ZCOMBO File: Error","Could not load the specified combos.");
2322 }
2323 else
2324 {
2325 displayinfo("ZCOMBO File: Success!","Loaded the source combos to your combo pages!");
2326 mark_save_dirty();
2327 }
2328 pack_fclose(f);
2329 }
2330
2331 }
2332 }
2333 }
2334
2335
2336
2337 static DIALOG save_dmaps_dlg[] =
2338 {
2339 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2340
2341
2342 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save DMaps (.zdmap)", NULL, NULL },
2343 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2344 //for future tabs
2345 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2346 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2347 //4
2348 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
2349 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2350 //6
2351 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Last", NULL, NULL },
2352 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2353 //8
2354 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
2355 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2356 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2357 };
2358
2359
2360 void savesomedmaps(const char *prompt,int32_t initialval)
2361 {
2362
2363 char firstdmap[8], lastdmap[8];
2364 int32_t first_dmap_id = 0; int32_t last_dmap_id = 0;
2365 sprintf(firstdmap,"%d",0);
2366 sprintf(lastdmap,"%d",1);
2367 //int32_t ret;
2368
2369
2370
2371 save_dmaps_dlg[0].dp2 = get_zc_font(font_lfont);
2372
2373 sprintf(firstdmap,"%d",0);
2374 sprintf(lastdmap,"%d",0);
2375
2376 save_dmaps_dlg[5].dp = firstdmap;
2377 save_dmaps_dlg[7].dp = lastdmap;
2378
2379 large_dialog(save_dmaps_dlg);
2380
2381 int32_t ret = do_zqdialog(save_dmaps_dlg,-1);
2382 jwin_center_dialog(save_dmaps_dlg);
2383
2384 if(ret == 8)
2385 {
2386 first_dmap_id = vbound(atoi(firstdmap), 0, MAXDMAPS-1);
2387 last_dmap_id = vbound(atoi(lastdmap), 0, MAXDMAPS-1);
2388
2389 if ( last_dmap_id < first_dmap_id )
2390 {
2391 int32_t swap = last_dmap_id;
2392 last_dmap_id = first_dmap_id;
2393 first_dmap_id = swap;
2394 }
2395 if(!prompt_for_new_file_compat("Export DMaps (.zdmap)","zdmap",NULL,datapath,false))
2396
2397
2398 mark_save_dirty();
2399
2400 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
2401 if(f)
2402 {
2403 if(!writesomedmaps(f,first_dmap_id,last_dmap_id,MAXDMAPS))
2404 {
2405 char name[PATH_MAX];
2406 extract_name(temppath,name,FILENAMEALL);
2407 displayinfo("Error",fmt::format("Unable to load {}",name));
2408 }
2409 else
2410 {
2411 char name[PATH_MAX];
2412 extract_name(temppath,name,FILENAMEALL);
2413 displayinfo("Success!",fmt::format("Saved {}",name));
2414 }
2415 }
2416 pack_fclose(f);
2417 }
2418 }
2419
2420 static DIALOG save_comboaliasfiles_dlg[] =
2421 {
2422 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2423
2424
2425 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save Combo Alias Pack", NULL, NULL },
2426 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2427 //for future tabs
2428 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2429 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2430 //4
2431 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
2432 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2433 //6
2434 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2435 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2436 //8
2437 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
2438 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2439 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2440 };
2441
2442
2443 void savesomecomboaliases(const char *prompt,int32_t initialval)
2444 {
2445
2446 char firsttile[8], tilecount[8];
2447 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2448 sprintf(firsttile,"%d",0);
2449 sprintf(tilecount,"%d",1);
2450 //int32_t ret;
2451
2452
2453
2454 save_comboaliasfiles_dlg[0].dp2 = get_zc_font(font_lfont);
2455
2456 sprintf(firsttile,"%d",0);
2457 sprintf(tilecount,"%d",1);
2458
2459 save_comboaliasfiles_dlg[5].dp = firsttile;
2460 save_comboaliasfiles_dlg[7].dp = tilecount;
2461
2462 large_dialog(save_comboaliasfiles_dlg);
2463
2464 int32_t ret = do_zqdialog(save_comboaliasfiles_dlg,-1);
2465 jwin_center_dialog(save_comboaliasfiles_dlg);
2466
2467 if(ret == 8)
2468 {
2469 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOALIASES-1));
2470 the_tile_count = vbound(atoi(tilecount), 1, (MAXCOMBOALIASES-1)-first_tile_id);
2471 if(prompt_for_new_file_compat("Save ZALIAS(.zalias)", "zalias", NULL,datapath,false))
2472 {
2473 char name[PATH_MAX];
2474 extract_name(temppath,name,FILENAMEALL);
2475 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
2476 if(f)
2477 {
2478 writecomboaliasfile(f,first_tile_id,the_tile_count);
2479 pack_fclose(f);
2480 displayinfo("Success!",fmt::format("Saved {}",name));
2481 }
2482 }
2483 }
2484 }
2485
2486
2487 static DIALOG read_comboaliaspack_dlg[] =
2488 {
2489 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2490
2491
2492 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Load Combo Pack To:", NULL, NULL },
2493 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2494 //for future tabs
2495 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2496 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2497 //4
2498 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Starting at:", NULL, NULL },
2499 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2500 //6
2501 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2502 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2503 //8
2504 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2505 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2506 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2507 };
2508
2509
2510 void writesomecomboaliases_to(const char *prompt,int32_t initialval)
2511 {
2512
2513 char firsttile[8];;
2514 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2515 sprintf(firsttile,"%d",0);
2516 //int32_t ret;
2517
2518
2519
2520 read_comboaliaspack_dlg[0].dp2 = get_zc_font(font_lfont);
2521
2522 sprintf(firsttile,"%d",0);
2523 //sprintf(tilecount,"%d",1);
2524
2525 read_comboaliaspack_dlg[5].dp = firsttile;
2526
2527 large_dialog(read_comboaliaspack_dlg);
2528
2529 int32_t ret = do_zqdialog(read_comboaliaspack_dlg,-1);
2530 jwin_center_dialog(read_comboaliaspack_dlg);
2531
2532 if(ret == 8)
2533 {
2534 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOALIASES-1));
2535 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
2536 if(prompt_for_existing_file_compat("Load ZALIAS(.zalias)", "zalias", NULL,datapath,false))
2537 {
2538 char name[256];
2539 extract_name(temppath,name,FILENAMEALL);
2540 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2541 if(f)
2542 {
2543
2544 if (!readcomboaliasfile_to_location(f,first_tile_id))
2545 {
2546 al_trace("Could not read from .zcombo packfile %s\n", name);
2547 displayinfo("ZALIAS File: Error","Could not load the specified combo aliases.");
2548 }
2549 else
2550 {
2551 displayinfo("ZALIAS File: Success!","Loaded the source combos to your combo alias table!");
2552 mark_save_dirty();
2553 }
2554 pack_fclose(f);
2555 }
2556 }
2557 }
2558 }
2559
2560
2561
2562
2563 //Doorsets
2564
2565 static DIALOG save_doorset_dlg[] =
2566 {
2567 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2568 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save Doorset", NULL, NULL },
2569 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2570 //for future tabs
2571 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2572 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2573 //4
2574 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
2575 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2576 //6
2577 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2578 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2579 //8
2580 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
2581 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2582 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2583 };
2584
2585
2586 void do_exportdoorset(const char *prompt,int32_t initialval)
2587 {
2588 char firstdoor[8], doorct[8];
2589 int32_t first_doorset_id = 0; int32_t the_doorset_count = 1;
2590 sprintf(firstdoor,"%d",0);
2591 sprintf(doorct,"%d",1);
2592 //int32_t ret;
2593 save_doorset_dlg[0].dp2 = get_zc_font(font_lfont);
2594
2595 sprintf(firstdoor,"%d",0);
2596 sprintf(doorct,"%d",1);
2597
2598 save_doorset_dlg[5].dp = firstdoor;
2599 save_doorset_dlg[7].dp = doorct;
2600
2601 large_dialog(save_doorset_dlg);
2602
2603 int32_t ret = do_zqdialog(save_doorset_dlg,-1);
2604 jwin_center_dialog(save_doorset_dlg);
2605
2606 if(ret == 8) //OK
2607 {
2608 /* sanity bounds
2609 first_doorset_id = vbound(atoi(firstdoor), 0, (MAXCOMBOS-1));
2610 the_doorset_count = vbound(atoi(doorct), 1, (MAXCOMBOS-1)-first_doorset_id);
2611 */
2612 if(prompt_for_new_file_compat("Save ZDOORS(.zdoors)", "zdoors", NULL,datapath,false))
2613 {
2614 char name[256];
2615 extract_name(temppath,name,FILENAMEALL);
2616 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
2617 if(f)
2618 {
2619 writezdoorsets(f,first_doorset_id,the_doorset_count);
2620 pack_fclose(f);
2621 displayinfo("Success!",fmt::format("Saved {}",name));
2622 }
2623 }
2624 }
2625 }
2626
2627 static DIALOG load_doorset_dlg[] =
2628 {
2629 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2630 { jwin_win_proc, 0, 0, 120, 124, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Door Set (Range)", NULL, NULL },
2631 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2632 //for future tabs
2633 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2634 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2635 //4
2636 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First:", NULL, NULL },
2637 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2638 //6
2639 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2640 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2641 //8
2642 { jwin_button_proc, 15, 92, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2643 { jwin_button_proc, 69, 92, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2644 //10
2645 { jwin_text_proc, 10, 64, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Dest", NULL, NULL },
2646 { jwin_edit_proc, 55, 63, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2647 //8
2648
2649 // { jwin_check_proc, 10, 46, 95, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Don't Overwrite", NULL, NULL },
2650
2651 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2652 };
2653
2654 void do_importdoorset(const char *prompt,int32_t initialval)
2655 {
2656
2657 char firstdoor[8], doorct[8], destid[8];
2658 int32_t first_doorset_id = 0; int32_t the_doorset_count = 1;
2659 int32_t the_dest_id = 0;
2660 sprintf(firstdoor,"%d",0);
2661 sprintf(doorct,"%d",1);
2662 sprintf(destid,"%d",0);
2663 //int32_t ret;
2664
2665 save_doorset_dlg[0].dp2 = get_zc_font(font_lfont);
2666
2667 load_doorset_dlg[5].dp = firstdoor;
2668 load_doorset_dlg[7].dp = doorct;
2669 load_doorset_dlg[11].dp = destid;
2670
2671 byte nooverwrite = 0;
2672
2673 large_dialog(load_doorset_dlg);
2674
2675 int32_t ret = do_zqdialog(load_doorset_dlg,-1);
2676 jwin_center_dialog(load_doorset_dlg);
2677
2678 if(ret == 8) //OK
2679 {
2680 //if (load_doorset_dlg[10].flags & D_SELECTED) nooverwrite = 1;
2681
2682 //sanity bound
2683 first_doorset_id = vbound(atoi(firstdoor), 0, door_combo_set_count);
2684 the_doorset_count = vbound(atoi(doorct), 1, door_combo_set_count);
2685 the_dest_id = vbound(atoi(destid), 0, door_combo_set_count);
2686 if(prompt_for_existing_file_compat("Load ZDOORS(.zdoors)", "zdoors", NULL,datapath,false))
2687 {
2688 char name[256];
2689 extract_name(temppath,name,FILENAMEALL);
2690 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2691 if(f)
2692 {
2693 int32_t ret = readzdoorsets(f,first_doorset_id,the_doorset_count, the_dest_id);
2694
2695 if (!ret)
2696 {
2697 al_trace("Could not read from .zdoors packfile %s\n", name);
2698 displayinfo("ZDOORS File: Error","Could not load the specified doorsets.");
2699 }
2700 else if ( ret == 1 )
2701 {
2702 displayinfo("ZDOORS File: Success!","Loaded the source doorsets!");
2703 mark_save_dirty();
2704 }
2705 else if ( ret == 2 )
2706 {
2707 displayinfo("ZDOORS File: Issue:","Targets exceed doorset count!");
2708 mark_save_dirty();
2709 }
2710 pack_fclose(f);
2711 }
2712 }
2713 }
2714 }
2715
2716 void update_combo_cycling()
2717 {
2718 Map.update_combo_cycling();
2719 }
2720
2721 void update_freeform_combos()
2722 {
2723 Map.update_freeform_combos();
2724 }
2725
2726 bool layers_valid(mapscr *tempscr)
2727 {
2728 for(int32_t i=0; i<6; i++)
2729 {
2730 if(tempscr->layermap[i]>map_count)
2731 {
2732 return false;
2733 }
2734 }
2735
2736 return true;
2737 }
2738
2739 void fix_layers(mapscr *tempscr, bool showwarning)
2740 {
2741 char buf[80]="";
2742
2743 for(int32_t i=0; i<6; i++)
2744 {
2745 if(tempscr->layermap[i]>map_count)
2746 {
2747 strcat(buf, "%d ");
2748 sprintf(buf, buf, i+1);
2749 tempscr->layermap[i]=0;
2750 }
2751 }
2752
2753 if(showwarning)
2754 {
2755 displayinfo("Invalid layers detected",
2756 fmt::format("One or more layers on this screen used"
2757 "maps that do not exist. The settings of these"
2758 "layers have been changed: {}", buf));
2759 }
2760 }
2761
2762 extern const char *colorlist(int32_t index, int32_t *list_size);
2763
2764 static char autobackup_str_buf[32];
2765 const char *autobackuplist(int32_t index, int32_t *list_size)
2766 {
2767 if(index>=0)
2768 {
2769 bound(index,0,10);
2770
2771 if(index==0)
2772 {
2773 sprintf(autobackup_str_buf,"Disabled");
2774 }
2775 else
2776 {
2777 sprintf(autobackup_str_buf,"%2d",index);
2778 }
2779
2780 return autobackup_str_buf;
2781 }
2782
2783 *list_size=11;
2784 return NULL;
2785 }
2786
2787 static char autosave_str_buf[32];
2788 const char *autosavelist(int32_t index, int32_t *list_size)
2789 {
2790 if(index>=0)
2791 {
2792 bound(index,0,10);
2793
2794 if(index==0)
2795 {
2796 sprintf(autosave_str_buf,"Disabled");
2797 }
2798 else
2799 {
2800 sprintf(autosave_str_buf,"%2d Minute%c",index,index>1?'s':0);
2801 }
2802
2803 return autosave_str_buf;
2804 }
2805
2806 *list_size=11;
2807 return NULL;
2808 }
2809
2810 const char *autosavelist2(int32_t index, int32_t *list_size)
2811 {
2812 if(index>=0)
2813 {
2814 bound(index,0,9);
2815 sprintf(autosave_str_buf,"%2d",index+1);
2816 return autosave_str_buf;
2817 }
2818
2819 *list_size=10;
2820 return NULL;
2821 }
2822
2823
2824 static int32_t options_1_list[] =
2825 {
2826 // dialog control number
2827 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1
2828 };
2829
2830 static int32_t options_2_list[] =
2831 {
2832 // dialog control number
2833 50, 51, -1
2834 };
2835
2836 static int32_t options_3_list[] =
2837 {
2838 // dialog control number
2839 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, -1
2840 };
2841 static int32_t options_4_list[] =
2842 {
2843 57, 58, 59, 60,
2844 -1
2845 };
2846
2847 static TABPANEL options_tabs[] =
2848 {
2849 // (text)
2850 { (char *)" 1 ", D_SELECTED, options_1_list, 0, NULL },
2851 { (char *)" 2 ", 0, options_2_list, 0, NULL },
2852 { (char *)" 3 ", 0, options_3_list, 0, NULL },
2853 { (char *)" 4 ", 0, options_4_list, 0, NULL },
2854 { NULL, 0, NULL, 0, NULL }
2855 };
2856
2857 12 static ListData autobackup_list(autobackuplist, &font);
2858 12 static ListData autosave_list(autosavelist, &font);
2859 12 static ListData autosave_list2(autosavelist2, &font);
2860 12 static ListData color_list(colorlist, &font);
2861 12 static ListData snapshotformat_list(snapshotformatlist, &font);
2862
2863 const char *dm_names[dm_max]=
2864 {
2865 "Normal",
2866 "Relational", // Removed.
2867 "Dungeon", // Removed.
2868 "Alias",
2869 "Pool",
2870 "Auto"
2871 };
2872
2873 void fix_drawing_mode_menu()
2874 {
2875 drawing_mode_menu.select_only_uid(draw_mode);
2876 }
2877
2878 int32_t onDrawingMode()
2879 {
2880 draw_mode=(draw_mode+1)%dm_max;
2881 int dm_relational = 1;
2882 if ((int)draw_mode == dm_relational)
2883 draw_mode += 2;
2884 fix_drawing_mode_menu();
2885 restore_mouse();
2886 return D_O_K;
2887 }
2888
2889 int32_t onDrawingModeNormal()
2890 {
2891 draw_mode=dm_normal;
2892 fix_drawing_mode_menu();
2893 restore_mouse();
2894 return D_O_K;
2895 }
2896
2897 int32_t onDrawingModeAlias()
2898 {
2899 if(draw_mode==dm_alias)
2900 {
2901 return onDrawingModeNormal();
2902 }
2903
2904 draw_mode=dm_alias;
2905 alias_cset_mod=0;
2906 fix_drawing_mode_menu();
2907 restore_mouse();
2908 return D_O_K;
2909 }
2910
2911 int32_t onDrawingModePool()
2912 {
2913 if(draw_mode==dm_cpool)
2914 {
2915 return onDrawingModeNormal();
2916 }
2917
2918 draw_mode=dm_cpool;
2919 fix_drawing_mode_menu();
2920 restore_mouse();
2921 return D_O_K;
2922 }
2923
2924 int32_t onDrawingModeAuto()
2925 {
2926 if (draw_mode == dm_auto)
2927 {
2928 return onDrawingModeNormal();
2929 }
2930
2931 draw_mode = dm_auto;
2932 fix_drawing_mode_menu();
2933 restore_mouse();
2934 return D_O_K;
2935 }
2936
2937 int32_t onReTemplate()
2938 {
2939 if (alert_confirm("Confirm Overwrite","Apply NES Dungeon template to all screens on this map?"))
2940 {
2941 Map.TemplateAll();
2942 refresh(rALL);
2943 }
2944
2945 return D_O_K;
2946 }
2947
2948 int32_t onUndo()
2949 {
2950 Map.UndoCommand();
2951 refresh(rALL);
2952 return D_O_K;
2953 }
2954
2955 int32_t onRedo()
2956 {
2957 Map.RedoCommand();
2958 refresh(rALL);
2959 return D_O_K;
2960 }
2961
2962 int32_t onCopy()
2963 {
2964 if(prv_mode)
2965 {
2966 Map.set_prvcmb(Map.get_prvcmb()==0?1:0);
2967 return D_O_K;
2968 }
2969
2970 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
2971 Map.Copy(screen);
2972 return D_O_K;
2973 }
2974
2975 int32_t onPaste()
2976 {
2977 if(key[KEY_LSHIFT] || key[KEY_RSHIFT])
2978 {
2979 if(CHECK_CTRL_CMD)
2980 return onPasteAllToAll();
2981 else return onPasteAll();
2982 }
2983 else if(CHECK_CTRL_CMD)
2984 return onPasteToAll();
2985 else
2986 {
2987 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
2988 Map.DoPasteScreenCommand(PasteCommandType::ScreenPartial, screen);
2989 }
2990 return D_O_K;
2991 }
2992
2993 int32_t onPasteAll()
2994 {
2995 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
2996 Map.DoPasteScreenCommand(PasteCommandType::ScreenAll, screen);
2997 return D_O_K;
2998 }
2999
3000 int32_t onPasteToAll()
3001 {
3002 if(alert_confirm("Confirmation", "You are about to paste to all screens on the current map.\nAre you sure?"))
3003 Map.DoPasteScreenCommand(PasteCommandType::ScreenPartialToEveryScreen);
3004 return D_O_K;
3005 }
3006
3007 int32_t onPasteAllToAll()
3008 {
3009 if(alert_confirm("Confirmation", "You are about to paste to all screens on the current map.\nAre you sure?"))
3010 Map.DoPasteScreenCommand(PasteCommandType::ScreenAllToEveryScreen);
3011 return D_O_K;
3012 }
3013
3014 int32_t onPasteUnderCombo()
3015 {
3016 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3017 Map.DoPasteScreenCommand(PasteCommandType::ScreenUnderCombo, screen);
3018 return D_O_K;
3019 }
3020
3021 int32_t onPasteSecretCombos()
3022 {
3023 Map.DoPasteScreenCommand(PasteCommandType::ScreenSecretCombos);
3024 return D_O_K;
3025 }
3026
3027 int32_t onPasteFFCombos()
3028 {
3029 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3030 Map.DoPasteScreenCommand(PasteCommandType::ScreenFFCombos, screen);
3031 return D_O_K;
3032 }
3033
3034 int32_t onPasteWarps()
3035 {
3036 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3037 Map.DoPasteScreenCommand(PasteCommandType::ScreenWarps, screen);
3038 return D_O_K;
3039 }
3040
3041 int32_t onPasteScreenData()
3042 {
3043 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3044 Map.DoPasteScreenCommand(PasteCommandType::ScreenData, screen);
3045 return D_O_K;
3046 }
3047
3048 int32_t onPasteWarpLocations()
3049 {
3050 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3051 Map.DoPasteScreenCommand(PasteCommandType::ScreenWarpLocations, screen);
3052 return D_O_K;
3053 }
3054
3055 int32_t onPasteDoors()
3056 {
3057 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3058 Map.DoPasteScreenCommand(PasteCommandType::ScreenDoors, screen);
3059 return D_O_K;
3060 }
3061
3062 int32_t onPasteLayers()
3063 {
3064 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3065 Map.DoPasteScreenCommand(PasteCommandType::ScreenLayers, screen);
3066 return D_O_K;
3067 }
3068
3069 int32_t onPastePalette()
3070 {
3071 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3072 Map.DoPasteScreenCommand(PasteCommandType::ScreenPalette, screen);
3073 return D_O_K;
3074 }
3075
3076 int32_t onPasteRoom()
3077 {
3078 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3079 Map.DoPasteScreenCommand(PasteCommandType::ScreenRoom, screen);
3080 return D_O_K;
3081 }
3082
3083 int32_t onPasteGuy()
3084 {
3085 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3086 Map.DoPasteScreenCommand(PasteCommandType::ScreenGuy, screen);
3087 return D_O_K;
3088 }
3089
3090 int32_t onPasteEnemies()
3091 {
3092 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3093 Map.DoPasteScreenCommand(PasteCommandType::ScreenEnemies, screen);
3094 return D_O_K;
3095 }
3096
3097 int32_t onDelete()
3098 {
3099 restore_mouse();
3100
3101 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3102 mapscr* scr = active_visible_screen ? active_visible_screen->scr : Map.CurrScr();
3103 if(!(scr->valid&mVALID) || alert_confirm("Confirm Delete","Delete this screen?"))
3104 {
3105 Map.DoClearScreenCommand(screen);
3106 }
3107
3108 mark_save_dirty();
3109 return D_O_K;
3110 }
3111
3112 int32_t onDeleteMap()
3113 {
3114 if (alert_confirm("Confirm Delete","Clear this entire map?"))
3115 {
3116 Map.clearmap(false);
3117 refresh(rALL);
3118 mark_save_dirty();
3119 }
3120
3121 return D_O_K;
3122 }
3123
3124 int32_t onToggleDarkness()
3125 {
3126 Map.CurrScr()->flags^=4;
3127 refresh(rMAP+rMENU);
3128 mark_save_dirty();
3129 return D_O_K;
3130 }
3131
3132 int32_t onIncMap()
3133 {
3134 int32_t m=Map.getCurrMap();
3135 Map.setCurrMap(m+1>=map_count?0:m+1);
3136 Map.setlayertarget(); //Needed to refresh the screen info. -Z ( 26th March, 2019 )
3137
3138 refresh(rALL);
3139 return D_O_K;
3140 }
3141
3142 int32_t onDecMap()
3143 {
3144 int32_t m = Map.getCurrMap();
3145 Map.setCurrMap((m-1<0)?map_count-1:zc_min(m-1,map_count-1));
3146 // Map.setCurrScr(Map.getCurrScr()); //Needed to refresh the screen info. -Z ( 26th March, 2019 )
3147 Map.setlayertarget(); //Needed to refresh the screen info. -Z ( 26th March, 2019 )
3148
3149 Map.refresh_color();
3150
3151 refresh(rALL);
3152 return D_O_K;
3153 }
3154
3155
3156 int32_t onDefault_Pals()
3157 {
3158 if (alert_confirm("Confirm Reset","Reset all palette data?"))
3159 {
3160 mark_save_dirty();
3161
3162 if(!init_colordata(true, &header, &QMisc))
3163 {
3164 displayinfo("Error","Palette reset failed.");
3165 }
3166
3167 refresh_pal();
3168 }
3169
3170 return D_O_K;
3171 }
3172
3173 int32_t onDefault_Combos()
3174 {
3175 if (alert_confirm("Confirm Reset","Reset combo data?"))
3176 {
3177 mark_save_dirty();
3178
3179 if(!init_combos(true, &header))
3180 {
3181 displayinfo("Error","Combo reset failed.");
3182 }
3183
3184 refresh(rALL);
3185 }
3186
3187 return D_O_K;
3188 }
3189
3190 int32_t onDefault_Items()
3191 {
3192 if (alert_confirm("Confirm Reset","Reset all items?"))
3193 {
3194 mark_save_dirty();
3195 reset_items(true, &header);
3196 }
3197
3198 return D_O_K;
3199 }
3200
3201 int32_t onDefault_Weapons()
3202 {
3203 if (alert_confirm("Confirm Reset","Reset weapon/misc. sprite data?"))
3204 {
3205 mark_save_dirty();
3206 reset_wpns(true, &header);
3207 }
3208
3209 return D_O_K;
3210 }
3211
3212 int32_t onDefault_Guys()
3213 {
3214 if (alert_confirm("Confirm Reset","Reset all enemy/NPC data?"))
3215 {
3216 mark_save_dirty();
3217 reset_guys();
3218 }
3219
3220 return D_O_K;
3221 }
3222
3223
3224 int32_t onDefault_Tiles()
3225 {
3226 if (alert_confirm("Confirm Reset","Reset all tiles?"))
3227 {
3228 mark_save_dirty();
3229
3230 if(!init_tiles(true, &header))
3231 {
3232 displayinfo("Error","Tile reset failed.");
3233 }
3234
3235 refresh(rALL);
3236 }
3237
3238 return D_O_K;
3239 }
3240
3241 void change_sfx(SAMPLE *sfx1, SAMPLE *sfx2);
3242
3243 int32_t onDefault_SFX()
3244 {
3245 if (alert_confirm("Confirm Reset", "Reset all sound effects?"))
3246 {
3247 mark_save_dirty();
3248 SAMPLE *temp_sample;
3249
3250 for(int32_t i=1; i<WAV_COUNT; i++)
3251 {
3252 temp_sample = (SAMPLE *)sfxdata[zc_min(i,Z35)].dat;
3253 change_sfx(&customsfxdata[i], temp_sample);
3254 sprintf(sfx_string[i],"s%03d",i);
3255
3256 if(i<Z35)
3257 strcpy(sfx_string[i], old_sfx_string[i-1]);
3258 set_bit(customsfxflag, i<Z35?1:0, i-1);
3259 }
3260 }
3261
3262 return D_O_K;
3263 }
3264
3265
3266 int32_t onDefault_MapStyles()
3267 {
3268 if (alert_confirm("Confirm Reset", "Reset all map styles?"))
3269 {
3270 mark_save_dirty();
3271 reset_mapstyles(true, &QMisc);
3272 }
3273
3274 return D_O_K;
3275 }
3276
3277 int onScrollScreen(int dir, bool warp)
3278 {
3279 Map.scroll(dir,warp);
3280 return D_O_K;
3281 }
3282
3283 int32_t onComboColLeft()
3284 {
3285 if(draw_mode==dm_cpool||draw_mode==dm_auto)
3286 ;
3287 else if((First[current_combolist]>0)&&(draw_mode!=dm_alias))
3288 {
3289 First[current_combolist]-=1;
3290 clear_tooltip();
3291 refresh(rCOMBOS);
3292 }
3293 else if((combo_alistpos[current_comboalist]>0)&&(draw_mode==dm_alias))
3294 {
3295 combo_alistpos[current_comboalist]-=1;
3296 clear_tooltip();
3297 refresh(rCOMBOS);
3298 }
3299
3300 clear_keybuf();
3301 return D_O_K;
3302 }
3303
3304 int32_t onComboColRight()
3305 {
3306 auto& sqr = (draw_mode == dm_alias ? comboaliaslist[current_comboalist] : combolist[current_combolist]);
3307 if(draw_mode==dm_cpool||draw_mode==dm_auto)
3308 ;
3309 else if((First[current_combolist]<(MAXCOMBOS-(sqr.w*sqr.h)))&&(draw_mode!=dm_alias))
3310 {
3311 First[current_combolist]+=1;
3312 clear_tooltip();
3313 refresh(rCOMBOS);
3314 }
3315 else if((combo_alistpos[current_comboalist]<(MAXCOMBOALIASES-(sqr.w*sqr.h)))&&(draw_mode==dm_alias))
3316 {
3317 combo_alistpos[current_comboalist]+=1;
3318 clear_tooltip();
3319 refresh(rCOMBOS);
3320 }
3321
3322 clear_keybuf();
3323 return D_O_K;
3324 }
3325
3326 int32_t onComboColUp()
3327 {
3328 auto& sqr = (draw_mode == dm_alias ? comboaliaslist[current_comboalist] : combolist[current_combolist]);
3329 if(draw_mode==dm_cpool||draw_mode==dm_auto)
3330 ;
3331 else if((First[current_combolist]>0)&&(draw_mode!=dm_alias))
3332 {
3333 First[current_combolist]-=zc_min(First[current_combolist],sqr.w);
3334 clear_tooltip();
3335
3336 refresh(rCOMBOS);
3337 }
3338 else if((combo_alistpos[current_comboalist]>0)&&(draw_mode==dm_alias))
3339 {
3340 combo_alistpos[current_comboalist]-=zc_min(combo_alistpos[current_comboalist],sqr.w);
3341 clear_tooltip();
3342 refresh(rCOMBOS);
3343 }
3344
3345 clear_keybuf();
3346 return D_O_K;
3347 }
3348
3349 int32_t onComboColDown()
3350 {
3351 auto& sqr = (draw_mode == dm_alias ? comboaliaslist[current_comboalist] : combolist[current_combolist]);
3352
3353 if(draw_mode==dm_cpool||draw_mode==dm_auto)
3354 ;
3355 else if((First[current_combolist]<(MAXCOMBOS-(sqr.w*sqr.h)))&&(draw_mode!=dm_alias))
3356 {
3357 First[current_combolist]+=zc_min((MAXCOMBOS-sqr.w)-First[current_combolist],sqr.w);
3358 clear_tooltip();
3359 refresh(rCOMBOS);
3360 }
3361 else if((combo_alistpos[current_comboalist]<(MAXCOMBOALIASES-(comboaliaslist[0].w*comboaliaslist[0].h)))&&(draw_mode==dm_alias))
3362 {
3363 combo_alistpos[current_comboalist]+=zc_min((MAXCOMBOALIASES-sqr.w)-combo_alistpos[current_comboalist],sqr.w);
3364 clear_tooltip();
3365 refresh(rCOMBOS);
3366 }
3367
3368 clear_keybuf();
3369 return D_O_K;
3370 }
3371
3372 void scrollup(int j)
3373 {
3374 switch(draw_mode)
3375 {
3376 case dm_alias:
3377 {
3378 auto& sqr = comboaliaslist[j];
3379 if(combo_alistpos[j]>0)
3380 {
3381 if(CHECK_CTRL_CMD)
3382 {
3383 combo_alistpos[j]=0;
3384 clear_tooltip();
3385 }
3386 else
3387 {
3388 combo_alistpos[j]-=zc_min(combo_alistpos[j],(sqr.w*sqr.h));
3389 clear_tooltip();
3390 }
3391
3392 refresh(rCOMBOS);
3393 }
3394 break;
3395 }
3396 case dm_cpool:
3397 {
3398 auto& sqr = comboaliaslist[j];
3399 if(combo_pool_listpos[j]>0)
3400 {
3401 if(CHECK_CTRL_CMD)
3402 {
3403 combo_pool_listpos[j]=0;
3404 clear_tooltip();
3405 }
3406 else
3407 {
3408 combo_pool_listpos[j]-=zc_min(combo_pool_listpos[j],(sqr.w*sqr.h));
3409 clear_tooltip();
3410 }
3411
3412 refresh(rCOMBOS);
3413 }
3414 break;
3415 }
3416 case dm_auto:
3417 {
3418 auto& sqr = comboaliaslist[j];
3419 if (combo_auto_listpos[j] > 0)
3420 {
3421 if (CHECK_CTRL_CMD)
3422 {
3423 combo_auto_listpos[j] = 0;
3424 clear_tooltip();
3425 }
3426 else
3427 {
3428 combo_auto_listpos[j] -= zc_min(combo_auto_listpos[j], (sqr.w * sqr.h));
3429 clear_tooltip();
3430 }
3431
3432 refresh(rCOMBOS);
3433 }
3434 break;
3435 }
3436 default:
3437 {
3438 auto& sqr = combolist[j];
3439 if(First[j]>0)
3440 {
3441 if(CHECK_CTRL_CMD)
3442 {
3443 First[j]-=zc_min(First[j],256);
3444 clear_tooltip();
3445 }
3446 else
3447 {
3448 First[j]-=zc_min(First[j],(sqr.w*sqr.h));
3449 clear_tooltip();
3450 }
3451
3452 refresh(rCOMBOS);
3453 }
3454 break;
3455 }
3456 }
3457 }
3458 void scrolldown(int j)
3459 {
3460 switch(draw_mode)
3461 {
3462 case dm_alias:
3463 {
3464 auto& sqr = comboaliaslist[j];
3465 if(combo_alistpos[j]<(MAXCOMBOALIASES-(sqr.w*sqr.h)))
3466 {
3467 if(CHECK_CTRL_CMD)
3468 {
3469 combo_alistpos[j]=MAXCOMBOALIASES-(sqr.w*sqr.h);
3470 clear_tooltip();
3471 }
3472 else
3473 {
3474 combo_alistpos[j]=zc_min((MAXCOMBOALIASES-(sqr.w*sqr.h)),combo_alistpos[j]+(sqr.w*sqr.h));
3475 clear_tooltip();
3476 }
3477
3478 refresh(rCOMBOS);
3479 }
3480 break;
3481 }
3482 case dm_cpool:
3483 {
3484 auto& sqr = comboaliaslist[j];
3485 if(combo_pool_listpos[j]<(MAXCOMBOALIASES-(sqr.w*sqr.h)))
3486 {
3487 if(CHECK_CTRL_CMD)
3488 {
3489 combo_pool_listpos[j]=MAXCOMBOALIASES-(sqr.w*sqr.h);
3490 clear_tooltip();
3491 }
3492 else
3493 {
3494 combo_pool_listpos[j]=zc_min((MAXCOMBOALIASES-(sqr.w*sqr.h)),combo_pool_listpos[j]+(sqr.w*sqr.h));
3495 clear_tooltip();
3496 }
3497
3498 refresh(rCOMBOS);
3499 }
3500 break;
3501 }
3502 case dm_auto:
3503 {
3504 auto& sqr = comboaliaslist[j];
3505 if (combo_auto_listpos[j] < (MAXCOMBOALIASES - (sqr.w * sqr.h)))
3506 {
3507 if (CHECK_CTRL_CMD)
3508 {
3509 combo_auto_listpos[j] = MAXCOMBOALIASES - (sqr.w * sqr.h);
3510 clear_tooltip();
3511 }
3512 else
3513 {
3514 combo_auto_listpos[j] = zc_min((MAXCOMBOALIASES - (sqr.w * sqr.h)), combo_pool_listpos[j] + (sqr.w * sqr.h));
3515 clear_tooltip();
3516 }
3517
3518 refresh(rCOMBOS);
3519 }
3520 break;
3521 }
3522 default:
3523 {
3524 auto& sqr = combolist[j];
3525 if(First[j]<(MAXCOMBOS-(sqr.w*sqr.h)))
3526 {
3527 if(CHECK_CTRL_CMD)
3528 {
3529 First[j]=zc_min((MAXCOMBOS-sqr.w*sqr.h),First[j]+256);
3530 clear_tooltip();
3531 }
3532 else
3533 {
3534 First[j]=zc_min((MAXCOMBOS-(sqr.w*sqr.h)),First[j]+(sqr.w*sqr.h));
3535 clear_tooltip();
3536 }
3537
3538 refresh(rCOMBOS);
3539 }
3540 break;
3541 }
3542 }
3543 }
3544
3545 int32_t onPgUp()
3546 {
3547 switch(draw_mode)
3548 {
3549 case dm_alias:
3550 scrollup(current_comboalist);
3551 break;
3552 case dm_cpool:
3553 scrollup(current_cpoollist);
3554 break;
3555 case dm_auto:
3556 scrollup(current_cautolist);
3557 break;
3558 default:
3559 scrollup(current_combolist);
3560 break;
3561 }
3562 return D_O_K;
3563 }
3564
3565 int32_t onPgDn()
3566 {
3567 switch(draw_mode)
3568 {
3569 case dm_alias:
3570 scrolldown(current_comboalist);
3571 break;
3572 case dm_cpool:
3573 scrolldown(current_cpoollist);
3574 break;
3575 case dm_auto:
3576 scrolldown(current_cautolist);
3577 break;
3578 default:
3579 scrolldown(current_combolist);
3580 break;
3581 }
3582 return D_O_K;
3583 }
3584
3585 int32_t onIncreaseCSet()
3586 {
3587 if(draw_mode!=dm_alias)
3588 {
3589 CSet=wrap(CSet+1,0,13);
3590 refresh(rCOMBOS+rMENU+rCOMBO);
3591 }
3592 else
3593 {
3594 alias_cset_mod=wrap(alias_cset_mod+1,0,13);
3595 }
3596 return D_O_K;
3597 }
3598
3599 int32_t onDecreaseCSet()
3600 {
3601 if(draw_mode!=dm_alias)
3602 {
3603 CSet=wrap(CSet-1,0,13);
3604 refresh(rCOMBOS+rMENU+rCOMBO);
3605 }
3606 else
3607 {
3608 alias_cset_mod=wrap(alias_cset_mod-1,0,13);
3609 }
3610 return D_O_K;
3611 }
3612
3613 int32_t onGotoPage()
3614 {
3615 if (draw_mode==dm_alias)
3616 {
3617 static const int PER_PAGE = 260;
3618 if(optional<int> v = call_get_num("Scroll to Alias Page", 0, MAXCOMBOALIASES/PER_PAGE-1, 0))
3619 combo_alistpos[current_comboalist] = *v*PER_PAGE;
3620 }
3621 else if (draw_mode==dm_cpool)
3622 {
3623 static const int PER_PAGE = 260;
3624 if(optional<int> v = call_get_num("Scroll to Combo Pool Page", 0, MAXCOMBOPOOLS/PER_PAGE-1, 0))
3625 combo_pool_listpos[current_cpoollist] = *v*PER_PAGE;
3626 }
3627 else if (draw_mode == dm_auto)
3628 {
3629 static const int PER_PAGE = 260;
3630 if(optional<int> v = call_get_num("Scroll to Auto Combo Page", 0, MAXAUTOCOMBOS/PER_PAGE-1, 0))
3631 combo_auto_listpos[current_cautolist] = *v*PER_PAGE;
3632 }
3633 else
3634 {
3635 static const int PER_PAGE = 256;
3636 if(optional<int> v = call_get_num("Scroll to Combo Page", 0, MAXCOMBOS/PER_PAGE-1, 0))
3637 First[current_combolist] = *v*PER_PAGE;
3638 }
3639
3640 return D_O_K;
3641 }
3642
3643 static char track_number_str_buf[MIDI_TRACK_BUFFER_SIZE] = {0};
3644 const char *tracknumlist(int32_t index, int32_t *list_size)
3645 {
3646 //memset(track_number_str_buf,0,50);
3647 if(index>=0)
3648 {
3649 bound(index,0,255);
3650 std::string name = zcmusic_get_track_name(zcmusic, index);
3651 sprintf(track_number_str_buf,"%02d %s",index+1, name.c_str());
3652 return track_number_str_buf;
3653 }
3654
3655 *list_size=zcmusic_get_tracks(zcmusic);
3656 return NULL;
3657 }
3658
3659 12 static ListData tracknum_list(tracknumlist, &font);
3660
3661 static DIALOG change_track_dlg[] =
3662 {
3663 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
3664 12 { jwin_win_proc, 60-12, 40, 200-16, 72, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Select Track", NULL, NULL },
3665 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
3666 12 { jwin_droplist_proc, 72-12, 60+4, 161, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &tracknum_list, NULL, NULL },
3667 12 { jwin_button_proc, 70, 87, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
3668 12 { jwin_button_proc, 150, 87, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
3669 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
3670 };
3671 // return list_dlg[2].d1;
3672
3673 int32_t changeTrack()
3674 {
3675 restore_mouse();
3676 change_track_dlg[0].dp2=get_zc_font(font_lfont);
3677 change_track_dlg[2].d1=gme_track;
3678
3679 large_dialog(change_track_dlg);
3680
3681 if(do_zqdialog(change_track_dlg,2)==3)
3682 {
3683 gme_track=change_track_dlg[2].d1;
3684 zcmusic_change_track(zcmusic, gme_track);
3685 }
3686
3687 return D_O_K;
3688 }
3689
3690 void set_media_tunes()
3691 {
3692 media_menu.select_uid(MENUID_MEDIA_TUNES, true);
3693 media_menu.select_uid(MENUID_MEDIA_PLAYMUSIC, false);
3694 disable_hotkey(ZQKEY_AMBIENT_MUSIC, false);
3695 disable_hotkey(ZQKEY_PLAY_MUSIC, false);
3696
3697 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, true);
3698 disable_hotkey(ZQKEY_CHANGE_TRACK, true);
3699 }
3700
3701 int32_t playMusic()
3702 {
3703 char *ext;
3704 bool ismidi=false;
3705 char allmusic_types[256];
3706 sprintf(allmusic_types, "%s;mid", zcmusic_types);
3707
3708 if(prompt_for_existing_file_compat("Load Music",(char*)allmusic_types,NULL,midipath,false))
3709 {
3710 strcpy(midipath,temppath);
3711
3712 ext=get_extension(midipath);
3713
3714 if(
3715 (stricmp(ext,"ogg")==0)||
3716 (stricmp(ext,"mp3")==0)||
3717 (stricmp(ext,"it")==0)||
3718 (stricmp(ext,"xm")==0)||
3719 (stricmp(ext,"s3m")==0)||
3720 (stricmp(ext,"mod")==0)||
3721 (stricmp(ext,"spc")==0)||
3722 (stricmp(ext,"gym")==0)||
3723 (stricmp(ext,"nsf")==0)||
3724 (stricmp(ext,"gbs")==0)||
3725 (stricmp(ext,"vgm")==0)
3726 )
3727 {
3728 ismidi=false;
3729 }
3730 else if((stricmp(ext,"mid")==0))
3731 {
3732 ismidi=true;
3733 }
3734 else
3735 {
3736 return D_O_K;
3737 }
3738
3739 zc_stop_midi();
3740
3741 if(zcmusic != NULL)
3742 {
3743 zcmusic_stop(zcmusic);
3744 zcmusic_unload_file(zcmusic);
3745 zcmusic = NULL;
3746 zcmixer->newtrack = NULL;
3747 }
3748
3749 if(ismidi)
3750 {
3751 packfile_password("");
3752 if((song=load_midi(midipath))!=NULL)
3753 {
3754 if(zc_play_midi(song,true)==0)
3755 {
3756 media_menu.select_uid(MENUID_MEDIA_TUNES, false);
3757 media_menu.select_uid(MENUID_MEDIA_PLAYMUSIC, true);
3758 disable_hotkey(ZQKEY_AMBIENT_MUSIC, false);
3759 disable_hotkey(ZQKEY_PLAY_MUSIC, false);
3760
3761 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, true);
3762 disable_hotkey(ZQKEY_CHANGE_TRACK, true);
3763 }
3764 }
3765 }
3766 else
3767 {
3768 gme_track=0;
3769 zcmusic = (ZCMUSIC*)zcmusic_load_file(midipath);
3770
3771 if(zcmusic!=NULL)
3772 {
3773 media_menu.select_uid(MENUID_MEDIA_TUNES, false);
3774 media_menu.select_uid(MENUID_MEDIA_PLAYMUSIC, true);
3775 disable_hotkey(ZQKEY_AMBIENT_MUSIC, false);
3776 disable_hotkey(ZQKEY_PLAY_MUSIC, false);
3777
3778 bool distrack = zcmusic_get_tracks(zcmusic)<2;
3779 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, distrack);
3780 disable_hotkey(ZQKEY_CHANGE_TRACK, distrack);
3781
3782 zcmusic_play(zcmusic, midi_volume);
3783 }
3784 }
3785 }
3786
3787 return D_O_K;
3788 }
3789
3790 int32_t playZCForever()
3791 {
3792 stopMusic();
3793
3794 zcmusic = zcmusic_load_file("assets/zc/ZC_Forever_HD.mp3");
3795 if (zcmusic)
3796 {
3797 zcmusic_play(zcmusic, midi_volume);
3798 set_media_tunes();
3799 }
3800 return D_O_K;
3801 }
3802
3803 // It took awhile to get these values right, so no meddlin'!
3804 int32_t playTune1()
3805 {
3806 return playTune(0);
3807 }
3808 int32_t playTune2()
3809 {
3810 return playTune(81);
3811 }
3812 int32_t playTune3()
3813 {
3814 return playTune(233);
3815 }
3816 int32_t playTune4()
3817 {
3818 return playTune(553);
3819 }
3820 int32_t playTune5()
3821 {
3822 return playTune(814);
3823 }
3824 int32_t playTune6()
3825 {
3826 return playTune(985);
3827 }
3828 int32_t playTune7()
3829 {
3830 return playTune(1153);
3831 }
3832 int32_t playTune8()
3833 {
3834 return playTune(1333);
3835 }
3836 int32_t playTune9()
3837 {
3838 return playTune(1556);
3839 }
3840 int32_t playTune10()
3841 {
3842 return playTune(1801);
3843 }
3844 int32_t playTune11()
3845 {
3846 return playTune(2069);
3847 }
3848 int32_t playTune12()
3849 {
3850 return playTune(2189);
3851 }
3852 int32_t playTune13()
3853 {
3854 return playTune(2569);
3855 }
3856 int32_t playTune14()
3857 {
3858 return playTune(2753);
3859 }
3860 int32_t playTune15()
3861 {
3862 return playTune(2856);
3863 }
3864 int32_t playTune16()
3865 {
3866 return playTune(3042);
3867 }
3868 int32_t playTune17()
3869 {
3870 return playTune(3125);
3871 }
3872 int32_t playTune18()
3873 {
3874 return playTune(3217);
3875 }
3876 int32_t playTune19()
3877 {
3878 return playTune(3296);
3879 }
3880
3881 int32_t playTune(int32_t pos)
3882 {
3883 zc_stop_midi();
3884
3885 if(zcmusic != NULL)
3886 {
3887 zcmusic_stop(zcmusic);
3888 zcmusic_unload_file(zcmusic);
3889 zcmusic = NULL;
3890 zcmixer->newtrack = NULL;
3891 }
3892
3893 if(zc_play_midi(asset_tunes_midi,true)==0)
3894 {
3895 zc_midi_seek(pos);
3896 set_media_tunes();
3897 }
3898
3899 return D_O_K;
3900 }
3901
3902 int32_t stopMusic()
3903 {
3904 zc_stop_midi();
3905
3906 if(zcmusic != NULL)
3907 {
3908 zcmusic_stop(zcmusic);
3909 zcmusic_unload_file(zcmusic);
3910 zcmusic = NULL;
3911 zcmixer->newtrack = NULL;
3912 }
3913
3914 media_menu.select_uid(MENUID_MEDIA_TUNES, false);
3915 media_menu.select_uid(MENUID_MEDIA_PLAYMUSIC, false);
3916 disable_hotkey(ZQKEY_AMBIENT_MUSIC, false);
3917 disable_hotkey(ZQKEY_PLAY_MUSIC, false);
3918
3919 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, true);
3920 disable_hotkey(ZQKEY_CHANGE_TRACK, true);
3921 return D_O_K;
3922 }
3923
3924 static int32_t gamemisc1_list[] =
3925 {
3926 5,6,7,8,
3927 9,10,11,12,
3928
3929 37,38,39,40,
3930 41,42,43,44,
3931
3932 71,72,73,74,
3933 75,76,77,78,
3934
3935 -1
3936 };
3937
3938 static int32_t gamemisc2_list[] =
3939 {
3940 13,14,15,16,
3941 17,18,19,20,
3942
3943 45,46,47,48,
3944 49,50,51,52,
3945
3946 79,80,81,82,
3947 83,84,85,86,
3948
3949 -1
3950 };
3951
3952 static int32_t gamemisc3_list[] =
3953 {
3954 21,22,23,24,
3955 25,26,27,28,
3956
3957 53,54,55,56,
3958 57,58,59,60,
3959
3960 87,88,89,90,
3961 91,92,93,94,
3962
3963 -1
3964 };
3965
3966 static int32_t gamemisc4_list[] =
3967 {
3968 29,30,31,32,
3969 33,34,35,36,
3970
3971 61,62,63,64,
3972 65,66,67,68,
3973
3974 95,96,97,98,
3975 99,100,101,102,
3976
3977 -1
3978 };
3979
3980 static TABPANEL gamemisc_tabs[] =
3981 {
3982 // (text)
3983 { (char *)" Misc[0-7] ", D_SELECTED, gamemisc1_list, 0, NULL },
3984 { (char *)" Misc[8-15] ", 0, gamemisc2_list, 0, NULL },
3985 { (char *)" Misc[16-23] ", 0, gamemisc3_list, 0, NULL },
3986 { (char *)" Misc[24-31] ", 0, gamemisc4_list, 0, NULL },
3987 { NULL, 0, NULL, 0, NULL }
3988 };
3989
3990 //to do: Make string boxes larger, and split into two tabs.
3991 static DIALOG gamemiscarray_dlg[] =
3992 {
3993 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
3994
3995 { jwin_win_proc, 0, 10, 310, 224, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Game->Misc[]", NULL, NULL },
3996 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
3997 { jwin_tab_proc, 3, 26, 304, 174, vc(14), vc(1), 0, 0, 1, 0, (void *) gamemisc_tabs, NULL, (void *)gamemiscarray_dlg },
3998 { d_dummy_proc, 240, 144, 40, 8, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
3999 { d_dummy_proc, 240, 144, 40, 8, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
4000
4001 //5
4002 { jwin_edit_proc, 8, 42, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4003 { jwin_edit_proc, 8, 42+20, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4004 { jwin_edit_proc, 8, 42+40, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4005 //8
4006 { jwin_edit_proc, 8, 42+60, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4007 { jwin_edit_proc, 8, 42+80, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4008 { jwin_edit_proc, 8, 42+100, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4009 { jwin_edit_proc, 8, 42+120, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4010 { jwin_edit_proc, 8, 42+140, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4011 //13
4012 { jwin_edit_proc, 8, 42, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4013 { jwin_edit_proc, 8, 42+20, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4014 { jwin_edit_proc, 8, 42+40, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4015 { jwin_edit_proc, 8, 42+60, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4016 { jwin_edit_proc, 8, 42+80, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4017 //18
4018 { jwin_edit_proc, 8, 42+100, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4019 { jwin_edit_proc, 8, 42+120, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4020 { jwin_edit_proc, 8, 42+140, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4021 { jwin_edit_proc, 8, 42, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4022 { jwin_edit_proc, 8, 42+20, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4023 //23
4024 { jwin_edit_proc, 8, 42+40, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4025 { jwin_edit_proc, 8, 42+60, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4026 { jwin_edit_proc, 8, 42+80, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4027 { jwin_edit_proc, 8, 42+100, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4028 { jwin_edit_proc, 8, 42+120, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4029 //28
4030 { jwin_edit_proc, 8, 42+140, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4031 { jwin_edit_proc, 8, 42, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4032 { jwin_edit_proc, 8, 42+20, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4033 { jwin_edit_proc, 8, 42+40, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4034 { jwin_edit_proc, 8, 42+60, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4035 //33
4036 { jwin_edit_proc, 8, 42+80, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4037 { jwin_edit_proc, 8, 42+100, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4038 { jwin_edit_proc, 8, 42+120, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4039 { jwin_edit_proc, 8, 42+140, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4040 //37
4041 { jwin_numedit_swap_zsint_proc, 96, 42, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4042 { jwin_numedit_swap_zsint_proc, 96, 42+20, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4043 //39
4044 { jwin_numedit_swap_zsint_proc, 96, 42+40, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4045 { jwin_numedit_swap_zsint_proc, 96, 42+60, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4046 { jwin_numedit_swap_zsint_proc, 96, 42+80, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4047 { jwin_numedit_swap_zsint_proc, 96, 42+100, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4048 { jwin_numedit_swap_zsint_proc, 96, 42+120, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4049 //44
4050 { jwin_numedit_swap_zsint_proc, 96, 42+140, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4051 { jwin_numedit_swap_zsint_proc, 96, 42, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4052 { jwin_numedit_swap_zsint_proc, 96, 42+20, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4053
4054 { jwin_numedit_swap_zsint_proc, 96, 42+40, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4055 { jwin_numedit_swap_zsint_proc, 96, 42+60, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4056 //49
4057 { jwin_numedit_swap_zsint_proc, 96, 42+80, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4058 { jwin_numedit_swap_zsint_proc, 96, 42+100, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4059 { jwin_numedit_swap_zsint_proc, 96, 42+120, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4060 { jwin_numedit_swap_zsint_proc, 96, 42+140, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4061 { jwin_numedit_swap_zsint_proc, 96, 42, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4062 //54
4063 { jwin_numedit_swap_zsint_proc, 96, 42+20, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4064 { jwin_numedit_swap_zsint_proc, 96, 42+40, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4065 { jwin_numedit_swap_zsint_proc, 96, 42+60, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4066 { jwin_numedit_swap_zsint_proc, 96, 42+80, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4067 { jwin_numedit_swap_zsint_proc, 96, 42+100, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4068 //59
4069 { jwin_numedit_swap_zsint_proc, 96, 42+120, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4070 { jwin_numedit_swap_zsint_proc, 96, 42+140, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4071 { jwin_numedit_swap_zsint_proc, 96, 42, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4072 { jwin_numedit_swap_zsint_proc, 96, 42+20, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4073 { jwin_numedit_swap_zsint_proc, 96, 42+40, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4074 //64
4075 { jwin_numedit_swap_zsint_proc, 96, 42+60, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4076 { jwin_numedit_swap_zsint_proc, 96, 42+80, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4077 { jwin_numedit_swap_zsint_proc, 96, 42+100, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4078 { jwin_numedit_swap_zsint_proc, 96, 42+120, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4079 { jwin_numedit_swap_zsint_proc, 96, 42+140, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4080 //69
4081 { jwin_button_proc, 70, 204, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
4082 { jwin_button_proc, 170, 204, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
4083
4084 //71
4085 { jwin_swapbtn_proc, 156, 42, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4086 { jwin_swapbtn_proc, 156, 62, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4087 { jwin_swapbtn_proc, 156, 82, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4088 { jwin_swapbtn_proc, 156, 102, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4089 { jwin_swapbtn_proc, 156, 122, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4090 { jwin_swapbtn_proc, 156, 142, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4091 { jwin_swapbtn_proc, 156, 162, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4092 { jwin_swapbtn_proc, 156, 182, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4093 //79
4094 { jwin_swapbtn_proc, 156, 42, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4095 { jwin_swapbtn_proc, 156, 62, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4096 { jwin_swapbtn_proc, 156, 82, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4097 { jwin_swapbtn_proc, 156, 102, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4098 { jwin_swapbtn_proc, 156, 122, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4099 { jwin_swapbtn_proc, 156, 142, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4100 { jwin_swapbtn_proc, 156, 162, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4101 { jwin_swapbtn_proc, 156, 182, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4102 //87
4103 { jwin_swapbtn_proc, 156, 42, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4104 { jwin_swapbtn_proc, 156, 62, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4105 { jwin_swapbtn_proc, 156, 82, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4106 { jwin_swapbtn_proc, 156, 102, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4107 { jwin_swapbtn_proc, 156, 122, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4108 { jwin_swapbtn_proc, 156, 142, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4109 { jwin_swapbtn_proc, 156, 162, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4110 { jwin_swapbtn_proc, 156, 182, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4111 //95
4112 { jwin_swapbtn_proc, 156, 42, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4113 { jwin_swapbtn_proc, 156, 62, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4114 { jwin_swapbtn_proc, 156, 82, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4115 { jwin_swapbtn_proc, 156, 102, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4116 { jwin_swapbtn_proc, 156, 122, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4117 { jwin_swapbtn_proc, 156, 142, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4118 { jwin_swapbtn_proc, 156, 162, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4119 { jwin_swapbtn_proc, 156, 182, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4120
4121 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
4122 };
4123
4124 // +----------+
4125 // | |
4126 // | View Pic |
4127 // | |
4128 // | |
4129 // | |
4130 // +----------+
4131
4132 BITMAP *pic=NULL;
4133 BITMAP *bmap=NULL;
4134 PALETTE picpal;
4135 PALETTE mappal;
4136 int32_t picx=0,picy=0,mapx=0,mapy=0,pblack,pwhite;
4137
4138 double picscale=1.0,mapscale=1.0;
4139 bool vp_showpal=true, vp_showsize=true, vp_center=true;
4140
4141 //INLINE int32_t pal_sum(RGB p) { return p.r + p.g + p.b; }
4142
4143 void get_bw(RGB *pal,int32_t &black,int32_t &white)
4144 {
4145 black=white=1;
4146
4147 for(int32_t i=1; i<256; i++)
4148 {
4149 if(pal_sum(pal[i])<pal_sum(pal[black]))
4150 black=i;
4151
4152 if(pal_sum(pal[i])>pal_sum(pal[white]))
4153 white=i;
4154 }
4155 }
4156
4157 void draw_bw_mouse(int32_t white, int32_t old_mouse, int32_t new_mouse)
4158 {
4159 blit(mouse_bmp[old_mouse][0],mouse_bmp[new_mouse][0],0,0,0,0,16,16);
4160
4161 for(int32_t y=0; y<16; y++)
4162 {
4163 for(int32_t x=0; x<16; x++)
4164 {
4165 if(getpixel(mouse_bmp[new_mouse][0],x,y)!=0)
4166 {
4167 putpixel(mouse_bmp[new_mouse][0],x,y,white);
4168 }
4169 }
4170 }
4171 }
4172
4173 int32_t load_the_pic(BITMAP **dst, PALETTE dstpal)
4174 {
4175 PALETTE temppal;
4176
4177 for(int32_t i=0; i<256; i++)
4178 {
4179 temppal[i]=dstpal[i];
4180 dstpal[i]=RAMpal[i];
4181 }
4182
4183 // set up the new palette
4184 for(int32_t i=0; i<64; i++)
4185 {
4186 dstpal[i].r = i;
4187 dstpal[i].g = i;
4188 dstpal[i].b = i;
4189 }
4190
4191 zc_set_palette(dstpal);
4192
4193 BITMAP *graypic = create_bitmap_ex(8,screen->w,screen->h);
4194 int32_t _w = screen->w-1;
4195 int32_t _h = screen->h-1;
4196
4197 // gray scale the current frame
4198 for(int32_t y=0; y<_h; y++)
4199 {
4200 for(int32_t x=0; x<_w; x++)
4201 {
4202 int32_t c = screen->line[y][x];
4203 int32_t gray = zc_min((temppal[c].r*42 + temppal[c].g*75 + temppal[c].b*14) >> 7, 63);
4204 graypic->line[y][x] = gray;
4205 }
4206 }
4207
4208 blit(graypic,screen,0,0,0,0,screen->w,screen->h);
4209 destroy_bitmap(graypic);
4210 #ifdef __GNUC__
4211 #pragma GCC diagnostic ignored "-Wformat-overflow"
4212 #endif
4213 char extbuf[2][80];
4214 memset(extbuf[0],0,80);
4215 memset(extbuf[1],0,80);
4216 sprintf(extbuf[0], "View Image (%s", snapshotformat_str[0][1]);
4217 strcpy(extbuf[1], snapshotformat_str[0][1]);
4218
4219 for(int32_t i=1; i<ssfmtMAX; ++i)
4220 {
4221 sprintf(extbuf[0], "%s, %s", extbuf[0], snapshotformat_str[i][1]);
4222 sprintf(extbuf[1], "%s;%s", extbuf[1], snapshotformat_str[i][1]);
4223 }
4224
4225 sprintf(extbuf[0], "%s)", extbuf[0]);
4226 #ifdef __GNUC__
4227 #pragma GCC diagnostic pop
4228 #endif
4229
4230 int32_t gotit = prompt_for_existing_file_compat(extbuf[0],extbuf[1],NULL,imagepath,true);
4231
4232 if(!gotit)
4233 {
4234 zc_set_palette(temppal);
4235 get_palette(dstpal);
4236 return 1;
4237 }
4238
4239 strcpy(imagepath,temppath);
4240
4241 if(*dst)
4242 {
4243 destroy_bitmap(*dst);
4244 }
4245
4246 for(int32_t i=0; i<256; i++)
4247 {
4248 dstpal[i].r = 0;
4249 dstpal[i].g = 0;
4250 dstpal[i].b = 0;
4251 }
4252
4253 *dst = load_bitmap(imagepath,picpal);
4254
4255 if(!*dst)
4256 {
4257 displayinfo("Error",fmt::format("Error loading image: {}",imagepath));
4258 return 2;
4259 }
4260
4261 // get_bw(picpal,pblack,pwhite);
4262 // draw_bw_mouse(pwhite);
4263 // gui_bg_color = pblack;
4264 // gui_fg_color = pwhite;
4265
4266 if(vp_center)
4267 {
4268 picx=picy=0;
4269 }
4270 else
4271 {
4272 picx=(*dst)->w-zq_screen_w;
4273 picy=(*dst)->h-zq_screen_h;
4274 }
4275
4276 return 0;
4277 }
4278 int load_the_pic_new(BITMAP **dst, PALETTE dstpal)
4279 {
4280 #ifdef __GNUC__
4281 #pragma GCC diagnostic ignored "-Wformat-overflow"
4282 #endif
4283 char extbuf[2][80];
4284 memset(extbuf[0],0,80);
4285 memset(extbuf[1],0,80);
4286 sprintf(extbuf[0], "View Image (%s", snapshotformat_str[0][1]);
4287 strcpy(extbuf[1], snapshotformat_str[0][1]);
4288
4289 for(int32_t i=1; i<ssfmtMAX; ++i)
4290 {
4291 sprintf(extbuf[0], "%s, %s", extbuf[0], snapshotformat_str[i][1]);
4292 sprintf(extbuf[1], "%s;%s", extbuf[1], snapshotformat_str[i][1]);
4293 }
4294
4295 sprintf(extbuf[0], "%s)", extbuf[0]);
4296 #ifdef __GNUC__
4297 #pragma GCC diagnostic pop
4298 #endif
4299
4300 int32_t gotit = prompt_for_existing_file_compat(extbuf[0],extbuf[1],NULL,imagepath,true);
4301
4302 if(!gotit)
4303 return 1;
4304
4305 strcpy(imagepath,temppath);
4306
4307 if(*dst)
4308 destroy_bitmap(*dst);
4309
4310 for(int32_t i=0; i<256; i++)
4311 {
4312 dstpal[i].r = 0;
4313 dstpal[i].g = 0;
4314 dstpal[i].b = 0;
4315 }
4316
4317 *dst = load_bitmap(imagepath,dstpal);
4318
4319 if(!*dst)
4320 {
4321 displayinfo("Error",fmt::format("Error loading image: {}",imagepath));
4322 return 2;
4323 }
4324
4325 if(vp_center)
4326 {
4327 picx=picy=0;
4328 }
4329 else
4330 {
4331 picx=(*dst)->w-zq_screen_w;
4332 picy=(*dst)->h-zq_screen_h;
4333 }
4334
4335 return 0;
4336 }
4337
4338 int32_t saveMapAsImage(ALLEGRO_BITMAP* bitmap)
4339 {
4340 char buf[200];
4341 int32_t num=0;
4342
4343 do
4344 {
4345 snprintf(buf, 200, "%szquest_map%05d.%s", get_snap_str(), ++num, snapshotformat_str[SnapshotFormat][1]);
4346 buf[199]='\0';
4347 }
4348 while(num<99999 && exists(buf));
4349
4350 if (num >= 99999)
4351 InfoDialog("Error", "Failed to save map image! Max map images (99999) already exist!").show();
4352 else if (!al_save_bitmap(buf, bitmap))
4353 InfoDialog("Error", fmt::format("Failed to save map image\n'{}'.", buf)).show();
4354
4355 return D_O_K;
4356 }
4357
4358 int32_t onViewPic()
4359 {
4360 return launchPicViewer(&pic,picpal,picx,picy,picscale,false);
4361 }
4362
4363 int32_t launchPicViewer(BITMAP **pictoview, PALETTE pal, int32_t& px2, int32_t& py2, double& scale, bool isviewingmap, bool skipmenu)
4364 {
4365 restore_mouse();
4366 BITMAP *buf;
4367 bool done=false, redraw=true;
4368
4369 popup_zqdialog_start();
4370
4371 // Always call load_the_map() when viewing the map.
4372 if((!*pictoview || isviewingmap) && (isviewingmap ? load_the_map(skipmenu) : load_the_pic(pictoview,pal)))
4373 {
4374 zc_set_palette(RAMpal);
4375 mapview_close();
4376 popup_zqdialog_end();
4377 return D_O_K;
4378 }
4379
4380 MapViewRTI* rti_map_view = mapview_get_rti();
4381
4382 zq_freeze_all_rti();
4383 if (isviewingmap)
4384 rti_map_view->freeze = false;
4385 else
4386 get_screen_rti()->freeze = false;
4387
4388 get_bw(pal,pblack,pwhite);
4389
4390 int32_t oldfgcolor = gui_fg_color;
4391 int32_t oldbgcolor = gui_bg_color;
4392
4393 buf = create_bitmap_ex(8,zq_screen_w,zq_screen_h);
4394
4395 if(!buf)
4396 {
4397 displayinfo("Error","Error creating temp bitmap");
4398 mapview_close();
4399 popup_zqdialog_end();
4400 return D_O_K;
4401 }
4402
4403 static LegacyBitmapRTI viewer_overlay_rti("viewer_overlay");
4404 viewer_overlay_rti.set_size(buf->w, buf->h);
4405 viewer_overlay_rti.a4_bitmap = buf;
4406 viewer_overlay_rti.transparency_index = 15;
4407 viewer_overlay_rti.freeze = false;
4408 get_root_rti()->add_child(&viewer_overlay_rti);
4409
4410 zc_set_palette(pal);
4411
4412 if(isviewingmap)
4413 {
4414 set_center_root_rti(false);
4415
4416 int sw = rti_map_view->width / 16;
4417 int sh = rti_map_view->height / 8;
4418 int screen = Map.getCurrScr();
4419 if (screen >= 0x00 && screen <= 0x7F)
4420 {
4421 auto root_transform = get_root_rti()->get_transform();
4422 int dw = al_get_display_width(all_get_display()) / root_transform.xscale;
4423 int dh = al_get_display_height(all_get_display()) / root_transform.yscale;
4424 mapx = (-(screen % 16) * sw - sw/2 + dw/2);
4425 mapy = (-(screen / 16) * sh - sh/2 + dh/2);
4426 }
4427 }
4428
4429 const double MIN_SCALE = 0.1;
4430 const double MAX_SCALE = 5.0;
4431 auto mouse_x = gui_mouse_x();
4432 auto mouse_y = gui_mouse_y();
4433 int mouse_off_x = 0, mouse_off_y = 0;
4434 double old_scale = scale;
4435 bool mouse_down = false;
4436
4437 do
4438 {
4439 HANDLE_CLOSE_ZQDLG();
4440 if(exiting_program) break;
4441 int w, h;
4442 if (isviewingmap)
4443 {
4444 w = rti_map_view->width;
4445 h = rti_map_view->height;
4446 }
4447 else
4448 {
4449 w = (*pictoview)->w;
4450 h = (*pictoview)->h;
4451 }
4452
4453 if (isviewingmap)
4454 {
4455 auto root_transform = get_root_rti()->get_transform();
4456 int dw = al_get_display_width(all_get_display()) / root_transform.xscale;
4457 int dh = al_get_display_height(all_get_display()) / root_transform.yscale;
4458 mapx = std::max(mapx, (int)(-w*scale + dw));
4459 mapy = std::max(mapy, (int)(-h*scale + dh));
4460 mapx = std::min(mapx, 0);
4461 mapy = std::min(mapy, 0);
4462 rti_map_view->set_transform({mapx, mapy, (float)scale, (float)scale});
4463 }
4464
4465 if(redraw)
4466 {
4467 clear_to_color(buf,15);
4468
4469 if (!isviewingmap)
4470 stretch_blit(*pictoview, buf, 0, 0, w, h,
4471 int32_t(zq_screen_w + (px2 - w) * scale) / 2, int32_t(zq_screen_h + (py2 - h) * scale) / 2,
4472 int32_t(w * scale), int32_t(h * scale));
4473
4474 if(vp_showpal)
4475 for(int32_t i=0; i<256; i++)
4476 rectfill(buf,((i&15)<<2)+zq_screen_w-64,((i>>4)<<2)+zq_screen_h-64,((i&15)<<2)+zq_screen_w-64+3,((i>>4)<<2)+zq_screen_h-64+3,i);
4477
4478 if(vp_showsize)
4479 {
4480 textprintf_ex(buf,font,0,zq_screen_h-8,pwhite,pblack,"%dx%d %.2f%%",w,h,scale*100.0);
4481 }
4482
4483 if (!isviewingmap)
4484 blit(buf,screen,0,0,0,0,zq_screen_w,zq_screen_h);
4485 redraw=false;
4486 }
4487
4488 custom_vsync();
4489
4490 int32_t step = 16;
4491 double scale_step = 0.95;
4492 double scale_bigstep = 2.0;
4493
4494 if(scale < 1.0)
4495 step = int32_t(4.0/ scale);
4496
4497 bool shift = (key[KEY_LSHIFT] || key[KEY_RSHIFT]);
4498 bool ctrl = CHECK_CTRL_CMD;
4499 if (shift)
4500 step <<= 2;
4501 if (ctrl)
4502 step >>= 1;
4503 if (shift && ctrl)
4504 {
4505 scale_step = 0.90;
4506 scale_bigstep = 4.0;
4507 }
4508 else if (shift)
4509 {
4510 scale_step = 0.80;
4511 scale_bigstep = 3.0;
4512 }
4513 else if(ctrl)
4514 {
4515 scale_step = 0.975;
4516 scale_bigstep = 1.5;
4517 }
4518
4519 if(key[KEY_UP])
4520 {
4521 py2+=step;
4522 redraw=true;
4523 }
4524
4525 if(key[KEY_DOWN])
4526 {
4527 py2-=step;
4528 redraw=true;
4529 }
4530
4531 if(key[KEY_LEFT])
4532 {
4533 px2+=step;
4534 redraw=true;
4535 }
4536
4537 if(key[KEY_RIGHT])
4538 {
4539 px2-=step;
4540 redraw=true;
4541 }
4542
4543 if (bool mouse_down_now = (gui_mouse_b() & 1); mouse_down_now != mouse_down)
4544 {
4545 mouse_down = mouse_down_now;
4546 if (mouse_down)
4547 {
4548 mouse_x = gui_mouse_x();
4549 mouse_y = gui_mouse_y();
4550 mouse_off_x = px2;
4551 mouse_off_y = py2;
4552 }
4553 }
4554
4555 if (mouse_down)
4556 {
4557 if (abs(old_scale - scale) > 0.01)
4558 {
4559 mouse_x = gui_mouse_x();
4560 mouse_y = gui_mouse_y();
4561 mouse_off_x = px2;
4562 mouse_off_y = py2;
4563 old_scale = scale;
4564 }
4565 px2 = mouse_off_x + (gui_mouse_x() - mouse_x);
4566 py2 = mouse_off_y + (gui_mouse_y() - mouse_y);
4567 }
4568
4569 if (mouse_z)
4570 {
4571 double new_scale = scale;
4572 for (int q = 0; q < mouse_z; ++q)
4573 new_scale /= scale_step;
4574 for (int q = 0; q > mouse_z; --q)
4575 new_scale *= scale_step;
4576 position_mouse_z(0);
4577
4578 auto mx = (gui_mouse_x() - px2) / scale;
4579 auto my = (gui_mouse_y() - py2) / scale;
4580 scale = vbound(new_scale, MAX_SCALE, MIN_SCALE);
4581
4582 px2 = gui_mouse_x() - (mx * scale);
4583 py2 = gui_mouse_y() - (my * scale);
4584 }
4585
4586 if(keypressed() && !redraw)
4587 switch(readkey()>>8)
4588 {
4589 case KEY_PGUP:
4590 scale *= scale_step;
4591
4592 if(scale<MIN_SCALE) scale = MIN_SCALE;
4593
4594 redraw=true;
4595 break;
4596
4597 case KEY_PGDN:
4598 scale /= scale_step;
4599
4600 if(scale>MAX_SCALE) scale = MAX_SCALE;
4601
4602 redraw = true;
4603 break;
4604
4605 case KEY_HOME:
4606 scale /= scale_bigstep;
4607
4608 if(scale<MIN_SCALE) scale = MIN_SCALE;
4609
4610 redraw = true;
4611 break;
4612
4613 case KEY_END:
4614 scale *= scale_bigstep;
4615
4616 if(scale>MAX_SCALE) scale = MAX_SCALE;
4617
4618 redraw = true;
4619 break;
4620
4621 case KEY_TILDE:
4622 scale = 0.5;
4623 redraw = true;
4624 break;
4625
4626 case KEY_Z:
4627 px2 = w-zq_screen_w;
4628 py2 = h-zq_screen_h;
4629 vp_center = false;
4630 redraw = true;
4631 break;
4632
4633 case KEY_1:
4634 scale = 1.0;
4635 redraw = true;
4636 break;
4637
4638 case KEY_2:
4639 scale = 2.0;
4640 redraw = true;
4641 break;
4642
4643 case KEY_3:
4644 scale = 3.0;
4645 redraw = true;
4646 break;
4647
4648 case KEY_4:
4649 scale = 4.0;
4650 redraw = true;
4651 break;
4652
4653 case KEY_5:
4654 scale = 5.0;
4655 redraw = true;
4656 break;
4657
4658 case KEY_C:
4659 px2 = py2 = 0;
4660 redraw = vp_center = true;
4661 break;
4662
4663 case KEY_S:
4664 vp_showsize = !vp_showsize;
4665 redraw = true;
4666 break;
4667
4668 case KEY_D:
4669 vp_showpal = !vp_showpal;
4670 redraw = true;
4671 break;
4672
4673 case KEY_P:
4674 if(isviewingmap) break;
4675
4676 case KEY_ESC:
4677 done = true;
4678 break;
4679
4680 case KEY_SPACE:
4681 mapview_close();
4682 if(isviewingmap ? load_the_map(skipmenu) : load_the_pic(pictoview,pal)==2)
4683 {
4684 done = true;
4685 }
4686 else
4687 {
4688 redraw = true;
4689 gui_bg_color = pblack;
4690 gui_fg_color = pwhite;
4691 scale = 1.0;
4692 zc_set_palette(pal);
4693 }
4694
4695 get_bw(pal,pblack,pwhite);
4696 break;
4697 }
4698 }
4699 while(!done);
4700
4701 destroy_bitmap(buf);
4702 zc_set_palette(RAMpal);
4703 gui_fg_color = oldfgcolor;
4704 gui_bg_color = oldbgcolor;
4705
4706 position_mouse_z(0);
4707 viewer_overlay_rti.remove();
4708 set_center_root_rti(true);
4709 mapview_close();
4710 popup_zqdialog_end();
4711 return D_O_K;
4712 }
4713
4714 static DIALOG loadmap_dlg[] =
4715 {
4716 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3)
4717 { jwin_win_proc, 0, 0, 225, 143, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "View Map", NULL, NULL },
4718 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4719 { jwin_text_proc, 32, 26, 96, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Resolution", NULL, NULL },
4720 // 3
4721 { jwin_radio_proc, 16, 36, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "1/4 - 1024x352", NULL, NULL },
4722 { jwin_radio_proc, 16, 46, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "1/2 - 2048x704", NULL, NULL },
4723 { jwin_radio_proc, 16, 56, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "Full - 4096x1408", NULL, NULL },
4724 { jwin_text_proc, 144, 26, 97, 9, vc(11), vc(1), 0, 0, 0, 0, (void *) "Options", NULL, NULL },
4725 // 7
4726 { jwin_check_proc, 144, 36, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Solidity", NULL, NULL },
4727 { jwin_check_proc, 144, 46, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Flags", NULL, NULL },
4728 { jwin_check_proc, 144, 56, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Dark", NULL, NULL },
4729 { jwin_check_proc, 144, 66, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Items", NULL, NULL },
4730 // 11
4731 { jwin_button_proc, 42, 110, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
4732 { jwin_button_proc, 122, 110, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
4733 { jwin_check_proc, 16, 88, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Save to Image", NULL, NULL },
4734 // 14
4735 { jwin_radio_proc, 16, 66, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void*)"2x - 8192x2816", NULL, NULL },
4736 { jwin_radio_proc, 16, 76, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void*)"4x - 16384x5632", NULL, NULL },
4737 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
4738 };
4739
4740 int32_t load_the_map(bool skipmenu)
4741 {
4742 static int32_t res = 0;
4743 static int32_t flags = cDEBUG;
4744
4745 loadmap_dlg[0].dp2 = get_zc_font(font_lfont);
4746 loadmap_dlg[3].flags = (res==2) ? D_SELECTED : 0;
4747 loadmap_dlg[4].flags = (res==1) ? D_SELECTED : 0;
4748 loadmap_dlg[5].flags = (res==0) ? D_SELECTED : 0;
4749 loadmap_dlg[7].flags = (flags&cWALK) ? D_SELECTED : 0;
4750 loadmap_dlg[8].flags = (flags&cFLAGS) ? D_SELECTED : 0;
4751 loadmap_dlg[9].flags = (flags&cNODARK) ? 0 : D_SELECTED;
4752 loadmap_dlg[10].flags = (flags&cNOITEM) ? 0 : D_SELECTED;
4753 loadmap_dlg[13].flags = 0;
4754 loadmap_dlg[14].flags = (res==3) ? D_SELECTED : 0;
4755 loadmap_dlg[15].flags = (res==4) ? D_SELECTED : 0;
4756
4757 if(!skipmenu)
4758 {
4759 large_dialog(loadmap_dlg);
4760
4761 if (do_zqdialog(loadmap_dlg, 11, true) != 11)
4762 {
4763 return 1;
4764 }
4765
4766 flags = cDEBUG;
4767
4768 if(loadmap_dlg[3].flags&D_SELECTED) res=2;
4769
4770 if(loadmap_dlg[4].flags&D_SELECTED) res=1;
4771
4772 if(loadmap_dlg[5].flags&D_SELECTED) res=0;
4773
4774 if(loadmap_dlg[7].flags&D_SELECTED) flags|=cWALK;
4775
4776 if(loadmap_dlg[8].flags&D_SELECTED) flags|=cFLAGS;
4777
4778 if(!(loadmap_dlg[9].flags&D_SELECTED)) flags|=cNODARK;
4779
4780 if(!(loadmap_dlg[10].flags&D_SELECTED)) flags|=cNOITEM;
4781
4782 if(loadmap_dlg[14].flags&D_SELECTED) res=3;
4783
4784 if(loadmap_dlg[15].flags&D_SELECTED) res=4;
4785 }
4786
4787 int32_t bw = (256*16)>>res;
4788 int32_t bh = (176*8)>>res;
4789 int32_t sw = 256>>res;
4790 int32_t sh = 176>>res;
4791 if(res>2)
4792 {
4793 bw = (256*16)<<(res-2);
4794 bh = (176*8)<<(res-2);
4795 sw = 256<<(res-2);
4796 sh = 176<<(res-2);
4797 }
4798
4799 mapview_open(flags, sw, sh, bw, bh);
4800
4801 vp_showpal = false;
4802 get_bw(picpal,pblack,pwhite);
4803 mapx = mapy = 0;
4804 mapscale = 1;
4805 imagepath[0] = 0;
4806
4807 if(loadmap_dlg[13].flags & D_SELECTED) saveMapAsImage(mapview_get_rti()->bitmap);
4808
4809 memcpy(mappal,RAMpal,sizeof(RAMpal));
4810
4811 return 0;
4812 }
4813
4814 int32_t onViewMap()
4815 {
4816 return onViewMapEx(false);
4817 }
4818 int32_t onViewMapEx(bool skipmenu)
4819 {
4820 int32_t temp_aligns=ShowMisalignments;
4821 ShowMisalignments=0;
4822 launchPicViewer(&bmap,mappal,mapx, mapy, mapscale,true,skipmenu);
4823 ShowMisalignments=temp_aligns;
4824 return D_O_K;
4825 }
4826
4827 static const char *mazedirstr[4] = {"North","South","West","East"};
4828 char _pathstr[40]="North,North,North,North";
4829
4830 char *pathstr(byte path[])
4831 {
4832 sprintf(_pathstr,"%s,%s,%s,%s",mazedirstr[path[0]],mazedirstr[path[1]],
4833 mazedirstr[path[2]],mazedirstr[path[3]]);
4834 return _pathstr;
4835 }
4836
4837 char _ticksstr[32]="99.99 seconds";
4838
4839 char *ticksstr(int32_t tics)
4840 {
4841 int32_t mins=tics/(60*60);
4842 tics=tics-(mins*60*60);
4843 int32_t secs=tics/60;
4844 tics=tics-(secs*60);
4845 tics=tics*100/60;
4846
4847 if(mins>0)
4848 {
4849 sprintf(_ticksstr,"%d:%02d.%02d",mins, secs, tics);
4850 }
4851 else
4852 {
4853 sprintf(_ticksstr,"%d.%02d seconds",secs, tics);
4854 }
4855
4856 return _ticksstr;
4857 }
4858
4859 ZC_FORMAT_PRINTF(7, 8)
4860 void textprintf_disabled(BITMAP *bmp, AL_CONST FONT *f, int32_t x, int32_t y, int32_t color_hl, int32_t color_sh, AL_CONST char *format, ...)
4861 {
4862 char buf[512];
4863 va_list ap;
4864 ASSERT(bmp);
4865 ASSERT(f);
4866 ASSERT(format);
4867
4868 va_start(ap, format);
4869 vsnprintf(buf, sizeof(buf), format, ap);
4870 va_end(ap);
4871
4872
4873 textout_ex(bmp, f, buf, x+1, y+1, color_hl, -1);
4874
4875 textout_ex(bmp, f, buf, x, y, color_sh, -1);
4876 }
4877
4878 ZC_FORMAT_PRINTF(7, 8)
4879 void textprintf_centre_disabled(BITMAP *bmp, AL_CONST FONT *f, int32_t x, int32_t y, int32_t color_hl, int32_t color_sh, AL_CONST char *format, ...)
4880 {
4881 char buf[512];
4882 va_list ap;
4883 ASSERT(bmp);
4884 ASSERT(f);
4885 ASSERT(format);
4886
4887 va_start(ap, format);
4888 vsnprintf(buf, sizeof(buf), format, ap);
4889 va_end(ap);
4890
4891 textout_centre_ex(bmp, f, buf, x+1, y+1, color_hl, -1);
4892 textout_centre_ex(bmp, f, buf, x, y, color_sh, -1);
4893 }
4894
4895 void draw_sqr_frame(size_and_pos const& sqr)
4896 {
4897 jwin_draw_frame(screen,sqr.x,sqr.y,sqr.tw(),sqr.th(),FR_DEEP);
4898 }
4899 void draw_sqr_icon(size_and_pos const& sqr, BITMAP* icon)
4900 {
4901 stretch_blit(icon, screen, 0, 0, 16, 16, sqr.x+2, sqr.y+2, sqr.tw()-4, sqr.th()-4);
4902 }
4903 void draw_sqr_nums(size_and_pos const& sqr, FONT* f, bool center, int num)
4904 {
4905 if(center)
4906 textprintf_centre_ex(screen,f,sqr.x+txtoffs_single.x,sqr.y+txtoffs_single.y,jwin_pal[jcBOXFG],-1,"%d",num);
4907 else
4908 textprintf_ex(screen,f,sqr.x+txtoffs_single.x,sqr.y+txtoffs_single.y,jwin_pal[jcBOXFG],-1,"%d",num);
4909 }
4910 void draw_sqr_nums(size_and_pos const& sqr, FONT* f, bool center, int num1, int num2)
4911 {
4912 if(center)
4913 {
4914 textprintf_centre_ex(screen,f,sqr.x+txtoffs_double_1.x,sqr.y+txtoffs_double_1.y,jwin_pal[jcBOXFG],-1,"%d",num1);
4915 textprintf_centre_ex(screen,f,sqr.x+txtoffs_double_2.x,sqr.y+txtoffs_double_2.y,jwin_pal[jcBOXFG],-1,"%d",num2);
4916 }
4917 else
4918 {
4919 textprintf_ex(screen,f,sqr.x+txtoffs_double_1.x,sqr.y+txtoffs_double_1.y,jwin_pal[jcBOXFG],-1,"%d",num1);
4920 textprintf_ex(screen,f,sqr.x+txtoffs_double_2.x,sqr.y+txtoffs_double_2.y,jwin_pal[jcBOXFG],-1,"%d",num2);
4921 }
4922 }
4923 void draw_sqr_btn(size_and_pos const& sqr, const char* txt, int flags, FONT* f = nullptr)
4924 {
4925 if(sqr.x < 0) return;
4926 FONT* tfont = font;
4927 if(f)
4928 font = f;
4929 draw_text_button(screen, sqr.x, sqr.y, sqr.tw(), sqr.th(), txt, 0, 0, flags, true);
4930 font = tfont;
4931 }
4932 void draw_sqr_btn(size_and_pos const& sqr, int icon, int flags, FONT* f = nullptr)
4933 {
4934 if(sqr.x < 0) return;
4935 FONT* tfont = font;
4936 if(f)
4937 font = f;
4938 draw_icon_button(screen, sqr.x, sqr.y, sqr.tw(), sqr.th(), icon, 0, 0, flags, true);
4939 font = tfont;
4940 }
4941
4942 void drawpanel()
4943 {
4944 mapscr *scr=Map.CurrScr();
4945 int32_t NextCombo = combobuf[Combo].nextcombo;
4946 int32_t NextCSet = combobuf[Combo].nextcset;
4947 if(combobuf[Combo].animflags & AF_CYCLEUNDERCOMBO)
4948 {
4949 NextCombo = scr->undercombo;
4950 NextCSet = scr->undercset;
4951 }
4952 if(combobuf[Combo].animflags & AF_CYCLENOCSET)
4953 NextCSet = CSet;
4954
4955 FONT* tfont = font;
4956 if(prv_mode)
4957 {
4958 jwin_draw_frame(screen,0,preview_panel.y,preview_panel.x+preview_panel.w, preview_panel.h, FR_WIN);
4959 rectfill(screen,preview_panel.x,preview_panel.y+2,preview_panel.x+preview_panel.w-3,preview_panel.y+preview_panel.h-3,jwin_pal[jcBOX]);
4960 }
4961 else
4962 {
4963 auto& sqr = main_panel;
4964 rectfill(screen,sqr.x,sqr.y,sqr.x+sqr.w-1,sqr.y+sqr.h-1, jwin_pal[jcBOX]);
4965 refresh(rSCRMAP);
4966 jwin_draw_frame(screen,sqr.x,sqr.y,sqr.w,sqr.h, FR_WIN);
4967
4968 font = get_custom_font(CFONT_GUI);
4969 draw_sqr_btn(squarepanel_swap_btn, "SWP", 0);
4970 if(compact_square_panels)
4971 {
4972 textprintf_centre_ex(screen,font,squarepanel_up_btn.cx(),squarepanel_up_btn.y-text_height(font)-2,jwin_pal[jcBOXFG],-1,"%d",compact_active_panel);
4973 draw_sqr_btn(squarepanel_up_btn, BTNICON_ARROW_UP, 0);
4974 draw_sqr_btn(squarepanel_down_btn, BTNICON_ARROW_DOWN, 0);
4975 }
4976 font = tfont;
4977
4978 FONT* sqr_text_font = (is_compact && compact_square_panels) ? get_custom_font(CFONT_GUI) : font;
4979 //Item:
4980 if(itemsqr_pos.x > -1)
4981 {
4982 draw_sqr_frame(itemsqr_pos);
4983 if(scr->hasitem)
4984 {
4985 rectfill(screen,itemsqr_pos.x+2,itemsqr_pos.y+2,itemsqr_pos.x+itemsqr_pos.tw()-3,itemsqr_pos.y+itemsqr_pos.th()-3,0);
4986 overtile16_scale(screen, itemsbuf[scr->item].tile,itemsqr_pos.x+2,itemsqr_pos.y+2,itemsbuf[scr->item].csets&15,0,itemsqr_pos.tw()-4,itemsqr_pos.th()-4);
4987 }
4988 else draw_sqr_icon(itemsqr_pos, icon_bmp[0][coord_frame]);
4989 draw_sqr_nums(itemsqr_pos, sqr_text_font, panel_align == 1, scr->itemx, scr->itemy);
4990 }
4991 //Flag:
4992 if(flagsqr_pos.x > -1)
4993 {
4994 draw_sqr_frame(flagsqr_pos);
4995 draw_sqr_icon(flagsqr_pos,flag_bmp[Flag%16][coord_frame]);
4996 draw_sqr_nums(flagsqr_pos, sqr_text_font, panel_align == 1, Flag);
4997 }
4998
4999 //Stairs:
5000 if(stairsqr_pos.x > -1)
5001 {
5002 draw_sqr_frame(stairsqr_pos);
5003 draw_sqr_icon(stairsqr_pos,icon_bmp[1][coord_frame]);
5004 draw_sqr_nums(stairsqr_pos, sqr_text_font, panel_align == 1, scr->stairx, scr->stairy);
5005 }
5006
5007 //Green arrival square:
5008 bool disabled_arrival = get_qr(qr_NOARRIVALPOINT);
5009 if(warparrival_pos.x > -1)
5010 {
5011 draw_sqr_frame(warparrival_pos);
5012 BITMAP* icon = icon_bmp[2][coord_frame];
5013 if(disabled_arrival)
5014 {
5015 icon = create_bitmap_ex(8,16,16);
5016 blit(icon_bmp[2][0], icon, 0, 0, 0, 0, 16, 16);
5017 replColor(icon, 0xE7, 0xEA, 0xEA, false);
5018 replColor(icon, 0xE8, 0xE2, 0xE2, false);
5019 }
5020
5021 draw_sqr_icon(warparrival_pos, icon);
5022 draw_sqr_nums(warparrival_pos, sqr_text_font, panel_align == 1, scr->warparrivalx, scr->warparrivaly);
5023
5024 if(disabled_arrival)
5025 destroy_bitmap(icon);
5026 }
5027
5028 //Blue return squares:
5029 for(int32_t i=0; i<4; i++)
5030 {
5031 if(warpret_pos[i].x < 0) continue;
5032 draw_sqr_frame(warpret_pos[i]);
5033 draw_sqr_icon(warpret_pos[i], icon_bmp[ICON_BMP_RETURN_A+i][coord_frame]);
5034 draw_sqr_nums(warpret_pos[i], sqr_text_font, panel_align == 1, scr->warpreturnx[i], scr->warpreturny[i]);
5035 }
5036
5037 // Enemies
5038 auto& ep = enemy_prev_pos;
5039 if(ep.x > -1)
5040 {
5041 if(ep.fw > -1)
5042 {
5043 rectfill(screen, ep.x, ep.y, ep.x+ep.tw()-1,ep.y+ep.th()-1,vc(0));
5044 rectfill(screen, ep.x+ep.fw, ep.y+ep.fh, ep.x+ep.tw()-1, ep.y+ep.th()-1, jwin_pal[jcBOX]);
5045 jwin_draw_frag_frame(screen, ep.x, ep.y, ep.tw(), ep.th(), ep.fw, ep.fh, FR_DEEP);
5046 }
5047 else
5048 {
5049 rectfill(screen, ep.x, ep.y, ep.x+ep.tw()-1,ep.y+ep.th()-1,vc(0));
5050 draw_sqr_frame(ep);
5051 }
5052 for(int32_t i=0; i< 10 && Map.CurrScr()->enemy[i]!=0; i++)
5053 {
5054 int32_t id = Map.CurrScr()->enemy[i];
5055 int32_t tile = get_qr(qr_NEWENEMYTILES) ? guysbuf[id].e_tile : guysbuf[id].tile;
5056 int32_t cset = guysbuf[id].cset;
5057 auto& sqr = ep.subsquare(i);
5058 if(tile)
5059 overtile16_scale(screen, tile+efrontfacingtile(id),sqr.x,sqr.y,cset,0,sqr.tw(),sqr.th());
5060 }
5061 }
5062 }
5063 font = tfont;
5064 }
5065
5066 void show_screen_error(const char *str, int32_t i, int32_t c)
5067 {
5068 rectfill(screen, screrrorpos.x-text_length(get_zc_font(font_lfont_l),str),screrrorpos.y-(i*16),screrrorpos.x,screrrorpos.y-((i-1)*16)-4,vc(0));
5069 textout_shadowed_ex(screen,get_zc_font(font_lfont_l), str,screrrorpos.x-text_length(get_zc_font(font_lfont_l),str),screrrorpos.y-(i*16),c,vc(0),-1);
5070 }
5071
5072 void tile_warp_notification(int32_t which, char *buf)
5073 {
5074 char letter = 'A'+which;
5075
5076 switch(Map.CurrScr()->tilewarptype[which])
5077 {
5078 case wtCAVE:
5079 sprintf(buf,"Tile Warp %c: Cave/Item Cellar",letter);
5080 break;
5081
5082 default:
5083 {
5084 char buf2[30];
5085
5086 if(strlen(DMaps[Map.CurrScr()->tilewarpdmap[which]].name)==0)
5087 {
5088 sprintf(buf2,"%d",Map.CurrScr()->tilewarpdmap[which]);
5089 }
5090 else
5091 sprintf(buf2,"%d-%s",Map.CurrScr()->tilewarpdmap[which],DMaps[Map.CurrScr()->tilewarpdmap[which]].name);
5092
5093 sprintf(buf,"Tile Warp %c: %s, %02X", letter, buf2, Map.CurrScr()->tilewarpscr[which]);
5094 break;
5095 }
5096
5097 case wtNOWARP:
5098 sprintf(buf,"Tile Warp %c: Cancel Warp", letter);
5099 break;
5100 }
5101 }
5102
5103 void side_warp_notification(int32_t which, int32_t dir, char *buf)
5104 {
5105 char letter = 'A'+which;
5106 char buf3[16];
5107
5108 if(dir==0 && Map.CurrScr()->timedwarptics)
5109 sprintf(buf3,"%s, Timed",mazedirstr[dir]);
5110 else if(dir==4)
5111 sprintf(buf3,"Timed");
5112 else
5113 strcpy(buf3, mazedirstr[dir]);
5114
5115 switch(Map.CurrScr()->sidewarptype[which])
5116 {
5117 case wtCAVE:
5118 sprintf(buf,"Side Warp %c (%s): Cave/Item Cellar",letter, buf3);
5119 break;
5120
5121 default:
5122 {
5123 // Destination DMap name
5124 if(strlen(DMaps[Map.CurrScr()->sidewarpdmap[which]].name)==0)
5125 {
5126 sprintf(buf,"Side Warp %c (%s): %d, %02X", letter, buf3, Map.CurrScr()->sidewarpdmap[which], Map.CurrScr()->sidewarpscr[which]);
5127 }
5128 else
5129 sprintf(buf,"Side Warp %c (%s): %d-%s, %02X", letter, buf3, Map.CurrScr()->sidewarpdmap[which],DMaps[Map.CurrScr()->sidewarpdmap[which]].name, Map.CurrScr()->sidewarpscr[which]);
5130
5131 break;
5132 }
5133
5134 case wtNOWARP:
5135 sprintf(buf,"Side Warp %c (%s): Cancel Warp", letter, buf3);
5136 break;
5137 }
5138 }
5139
5140 static bool arrowcursor = true; // Used by combo aliases and Combo Brush cursors. -L
5141
5142 void xout(BITMAP* dest, int x, int y, int x2, int y2, int c, int bgc = -1)
5143 {
5144 //BG Fill
5145 if(bgc > -1)
5146 rectfill(dest, x, y, x2, y2, bgc);
5147 ++x; ++y; --x2; --y2;
5148 //Border
5149 safe_rect(dest, x, y, x2, y2, c);
5150 //line(dest, x, y, x2, y, c);
5151 //line(dest, x, y, x, y2, c);
5152 //X
5153 line(dest, x, y, x2, y2, c);
5154 line(dest, x, y2, x2, y, c);
5155 }
5156
5157 void put_autocombo_engravings(BITMAP* dest, combo_auto const& ca, bool selected, int32_t x, int32_t y, int32_t scale)
5158 {
5159 if (!ca.valid())
5160 {
5161 if (ca.getDisplay() > 0)
5162 put_engraving(dest, x, y, 15, scale);
5163 }
5164 else
5165 {
5166 if (ca.getType() == AUTOCOMBO_Z4 || ca.getType() == AUTOCOMBO_DOR)
5167 {
5168 byte hei = vbound(ca.getArg() + 1, 1, 9);
5169 if (selected)
5170 hei = vbound(cauto_height, 1, 9);
5171 put_engraving(dest, x, y, 15 - hei, scale);
5172 }
5173 }
5174 }
5175
5176 static void draw_screenunit_map_screen2(VisibleScreen visible_screen)
5177 {
5178 BITMAP* screen_bitmap = screen;
5179
5180 int num_screens_to_draw = Map.getViewSize();
5181 int screen = visible_screen.screen;
5182 int xoff = visible_screen.xoff;
5183 int yoff = visible_screen.yoff;
5184
5185 mapscr* scr = visible_screen.scr;
5186 if (!layers_valid(scr))
5187 fix_layers(scr, true);
5188
5189 clear_to_color(mapscreenbmp, 0);
5190
5191 int view_scr_x = Map.getViewScr() % 16;
5192 int view_scr_y = Map.getViewScr() / 16;
5193 int scr_x = screen % 16;
5194 int scr_y = screen / 16;
5195 int edge_xoff = 0, edge_yoff = 0;
5196 if(showedges)
5197 {
5198 if (scr_x == view_scr_x)
5199 edge_xoff = 16;
5200 else
5201 xoff -= 16;
5202
5203 if (scr_y == view_scr_y)
5204 edge_yoff = 16;
5205 else
5206 yoff -= 16;
5207 }
5208
5209 // TODO: should be better to move this out of draw_screenunit_map_screen.
5210 if (showedges && screen < 128)
5211 {
5212 bool peek_above = scr_y == view_scr_y;
5213 bool peek_below = scr_y == view_scr_y + num_screens_to_draw - 1;
5214 bool peek_left = scr_x == view_scr_x;
5215 bool peek_right = scr_x == view_scr_x + num_screens_to_draw - 1;
5216
5217 int right_col = 272 - (num_screens_to_draw > 1 ? 16 : 0);
5218 int bottom_row = 192 - (num_screens_to_draw > 1 ? 16 : 0);
5219
5220 //not the first row of screens
5221 if (peek_above)
5222 {
5223 if(screen>15 && !NoScreenPreview)
5224 {
5225 Map.drawrow(mapscreenbmp, edge_xoff, 0, Flags, 160, -1, screen-16);
5226 }
5227 else
5228 {
5229 Map.drawstaticrow(mapscreenbmp, edge_xoff, 0);
5230 }
5231 }
5232
5233 //not the last row of screens
5234 if (peek_below)
5235 {
5236 if(screen + 16 < 0x80 && !NoScreenPreview)
5237 {
5238 Map.drawrow(mapscreenbmp, edge_xoff, bottom_row, Flags, 0, -1, screen+16);
5239 }
5240 else
5241 {
5242 Map.drawstaticrow(mapscreenbmp, edge_xoff, bottom_row);
5243 }
5244 }
5245
5246 //not the first column of screens
5247 if (peek_left)
5248 {
5249 if(screen&0x0F && !NoScreenPreview)
5250 {
5251 Map.drawcolumn(mapscreenbmp, 0, edge_yoff, Flags, 15, -1, screen-1);
5252 }
5253 else
5254 {
5255 Map.drawstaticcolumn(mapscreenbmp, 0, edge_yoff);
5256 }
5257 }
5258
5259 //not the last column of screens
5260 if (peek_right)
5261 {
5262 if((screen&0x0F)<15 && !NoScreenPreview)
5263 {
5264 Map.drawcolumn(mapscreenbmp, right_col, edge_yoff, Flags, 0, -1, screen+1);
5265 }
5266 else
5267 {
5268 Map.drawstaticcolumn(mapscreenbmp, right_col, edge_yoff);
5269 }
5270 }
5271
5272 //not the first row or first column of screens
5273 if (peek_above && peek_left)
5274 {
5275 if((screen>15)&&(screen&0x0F) && !NoScreenPreview)
5276 {
5277 Map.drawblock(mapscreenbmp, 0, 0, Flags, 175, -1, screen-17);
5278 }
5279 else
5280 {
5281 Map.drawstaticblock(mapscreenbmp, 0, 0);
5282 }
5283 }
5284
5285 //not the first row or last column of screens
5286 if (peek_above && peek_right)
5287 {
5288 if((screen>15)&&((screen&0x0F)<15) && !NoScreenPreview)
5289 {
5290 Map.drawblock(mapscreenbmp, right_col, 0, Flags, 160, -1, screen-15);
5291 }
5292 else
5293 {
5294 Map.drawstaticblock(mapscreenbmp, right_col, 0);
5295 }
5296 }
5297
5298 //not the last row or first column of screens
5299 if (peek_below && peek_left)
5300 {
5301 if((screen<112)&&(screen&0x0F) && !NoScreenPreview)
5302 {
5303 Map.drawblock(mapscreenbmp, 0, bottom_row, Flags, 15, -1, screen+15);
5304 }
5305 else
5306 {
5307 Map.drawstaticblock(mapscreenbmp, 0, bottom_row);
5308 }
5309 }
5310
5311 //not the last row or last column of screens
5312 if (peek_below && peek_right)
5313 {
5314 if((screen<112)&&((screen&0x0F)<15) && !NoScreenPreview)
5315 {
5316 Map.drawblock(mapscreenbmp, right_col, bottom_row, Flags, 0, -1, screen+17);
5317 }
5318 else
5319 {
5320 Map.drawstaticblock(mapscreenbmp, right_col, bottom_row);
5321 }
5322 }
5323 }
5324
5325 if (ShowSquares && Map.getViewSize() < 4)
5326 {
5327 if(scr->stairx || scr->stairy)
5328 {
5329 int32_t x1 = scr->stairx+edge_xoff;
5330 int32_t y1 = scr->stairy+edge_yoff;
5331 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,vc(14));
5332 }
5333
5334 if(scr->warparrivalx || scr->warparrivaly)
5335 {
5336 int32_t x1 = scr->warparrivalx +edge_xoff;
5337 int32_t y1 = scr->warparrivaly +edge_yoff;
5338 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,vc(10));
5339 }
5340
5341 for(int32_t i=0; i<4; i++) if(scr->warpreturnx[i] || scr->warpreturny[i])
5342 {
5343 int32_t x1 = scr->warpreturnx[i]+edge_xoff;
5344 int32_t y1 = scr->warpreturny[i]+edge_yoff;
5345 int32_t clr = vc(9);
5346
5347 if(FlashWarpSquare==i)
5348 {
5349 if(!FlashWarpClk)
5350 FlashWarpSquare=-1;
5351 else if(!(--FlashWarpClk%3))
5352 clr = vc(15);
5353 }
5354
5355 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,clr);
5356 }
5357 }
5358
5359 if(ShowFFCs)
5360 {
5361 mapscr* ffscr = prv_mode ? Map.get_prvscr() : scr;
5362 int num_ffcs = ffscr->numFFC();
5363 for(int32_t i=num_ffcs-1; i>=0; i--)
5364 {
5365 ffcdata& ff = ffscr->ffcs[i];
5366 if(ff.data !=0 && (ff.layer >= CurrentLayer || (ff.flags&ffc_overlay)))
5367 {
5368 auto x = ff.x+edge_xoff;
5369 auto y = ff.y+edge_yoff;
5370 safe_rect(mapscreenbmp, x+0, y+0, x+ff.txsz*16-1, y+ff.tysz*16-1, vc(12));
5371 }
5372 }
5373 }
5374
5375 if(num_screens_to_draw == 1 && !(Flags&cDEBUG) && pixeldb==1)
5376 {
5377 for(int32_t j=168; j<176; j++)
5378 {
5379 for(int32_t i=0; i<256; i++)
5380 {
5381 if(((i^j)&1)==0)
5382 {
5383 putpixel(mapscreenbmp,edge_xoff+i,
5384 edge_yoff+j,vc(blackout_color));
5385 }
5386 }
5387 }
5388 }
5389
5390 int w = mapscreenbmp->w * mapscreen_single_scale;
5391 int h = mapscreenbmp->h * mapscreen_single_scale;
5392 stretch_blit(mapscreenbmp, screen_bitmap, 0, 0, mapscreenbmp->w, mapscreenbmp->h, mapscreen_x + xoff, mapscreen_y + yoff, w, h);
5393 }
5394
5395 static void draw_screenunit_map_screen(VisibleScreen visible_screen)
5396 {
5397 BITMAP* screen_bitmap = screen;
5398
5399 if (HighQualityScreenRendering) return draw_screenunit_map_screen2(visible_screen);
5400
5401 int num_screens_to_draw = Map.getViewSize();
5402 int screen = visible_screen.screen;
5403 int xoff = visible_screen.xoff;
5404 int yoff = visible_screen.yoff;
5405
5406 mapscr* scr = visible_screen.scr;
5407 if (!layers_valid(scr))
5408 fix_layers(scr, true);
5409
5410 clear_to_color(mapscreenbmp, jwin_pal[jcBOX]);
5411 if (LayerDitherBG > -1)
5412 {
5413 if (LayerDitherSz > 0)
5414 ditherblit(mapscreenbmp, nullptr, vc(LayerDitherBG), dithChecker, LayerDitherSz);
5415 else
5416 clear_to_color(mapscreenbmp, vc(LayerDitherBG));
5417 }
5418
5419 int view_scr_x = Map.getViewScr() % 16;
5420 int view_scr_y = Map.getViewScr() / 16;
5421 int scr_x = screen % 16;
5422 int scr_y = screen / 16;
5423 int edge_xoff = 0, edge_yoff = 0;
5424 if(showedges)
5425 {
5426 if (scr_x == view_scr_x)
5427 edge_xoff = 16;
5428 else
5429 xoff -= 16;
5430
5431 if (scr_y == view_scr_y)
5432 edge_yoff = 16;
5433 else
5434 yoff -= 16;
5435 }
5436
5437 combotile_add_x = mapscreen_x + xoff;
5438 combotile_add_y = mapscreen_y + yoff;
5439 combotile_mul_x = mapscreen_single_scale;
5440 combotile_mul_y = mapscreen_single_scale;
5441 Map.draw(mapscreenbmp, scr_x == view_scr_x && showedges ? 16 : 0, scr_y == view_scr_y && showedges ? 16 : 0, Flags, Map.getCurrMap(), screen, ActiveLayerHighlight ? CurrentLayer : -1);
5442 combotile_add_x = 0;
5443 combotile_add_y = 0;
5444 combotile_mul_x = 1;
5445 combotile_mul_y = 1;
5446
5447 // TODO: should be better to move this out of draw_screenunit_map_screen.
5448 if (showedges && screen < 128)
5449 {
5450 bool peek_above = scr_y == view_scr_y;
5451 bool peek_below = scr_y == view_scr_y + num_screens_to_draw - 1;
5452 bool peek_left = scr_x == view_scr_x;
5453 bool peek_right = scr_x == view_scr_x + num_screens_to_draw - 1;
5454
5455 int right_col = 272 - (num_screens_to_draw > 1 ? 16 : 0);
5456 int bottom_row = 192 - (num_screens_to_draw > 1 ? 16 : 0);
5457
5458 //not the first row of screens
5459 if (peek_above)
5460 {
5461 if(screen>15 && !NoScreenPreview)
5462 {
5463 Map.drawrow(mapscreenbmp, edge_xoff, 0, Flags, 160, -1, screen-16);
5464 }
5465 else
5466 {
5467 Map.drawstaticrow(mapscreenbmp, edge_xoff, 0);
5468 }
5469 }
5470
5471 //not the last row of screens
5472 if (peek_below)
5473 {
5474 if(screen + 16 < 0x80 && !NoScreenPreview)
5475 {
5476 Map.drawrow(mapscreenbmp, edge_xoff, bottom_row, Flags, 0, -1, screen+16);
5477 }
5478 else
5479 {
5480 Map.drawstaticrow(mapscreenbmp, edge_xoff, bottom_row);
5481 }
5482 }
5483
5484 //not the first column of screens
5485 if (peek_left)
5486 {
5487 if(screen&0x0F && !NoScreenPreview)
5488 {
5489 Map.drawcolumn(mapscreenbmp, 0, edge_yoff, Flags, 15, -1, screen-1);
5490 }
5491 else
5492 {
5493 Map.drawstaticcolumn(mapscreenbmp, 0, edge_yoff);
5494 }
5495 }
5496
5497 //not the last column of screens
5498 if (peek_right)
5499 {
5500 if((screen&0x0F)<15 && !NoScreenPreview)
5501 {
5502 Map.drawcolumn(mapscreenbmp, right_col, edge_yoff, Flags, 0, -1, screen+1);
5503 }
5504 else
5505 {
5506 Map.drawstaticcolumn(mapscreenbmp, right_col, edge_yoff);
5507 }
5508 }
5509
5510 //not the first row or first column of screens
5511 if (peek_above && peek_left)
5512 {
5513 if((screen>15)&&(screen&0x0F) && !NoScreenPreview)
5514 {
5515 Map.drawblock(mapscreenbmp, 0, 0, Flags, 175, -1, screen-17);
5516 }
5517 else
5518 {
5519 Map.drawstaticblock(mapscreenbmp, 0, 0);
5520 }
5521 }
5522
5523 //not the first row or last column of screens
5524 if (peek_above && peek_right)
5525 {
5526 if((screen>15)&&((screen&0x0F)<15) && !NoScreenPreview)
5527 {
5528 Map.drawblock(mapscreenbmp, right_col, 0, Flags, 160, -1, screen-15);
5529 }
5530 else
5531 {
5532 Map.drawstaticblock(mapscreenbmp, right_col, 0);
5533 }
5534 }
5535
5536 //not the last row or first column of screens
5537 if (peek_below && peek_left)
5538 {
5539 if((screen<112)&&(screen&0x0F) && !NoScreenPreview)
5540 {
5541 Map.drawblock(mapscreenbmp, 0, bottom_row, Flags, 15, -1, screen+15);
5542 }
5543 else
5544 {
5545 Map.drawstaticblock(mapscreenbmp, 0, bottom_row);
5546 }
5547 }
5548
5549 //not the last row or last column of screens
5550 if (peek_below && peek_right)
5551 {
5552 if((screen<112)&&((screen&0x0F)<15) && !NoScreenPreview)
5553 {
5554 Map.drawblock(mapscreenbmp, right_col, bottom_row, Flags, 0, -1, screen+17);
5555 }
5556 else
5557 {
5558 Map.drawstaticblock(mapscreenbmp, right_col, bottom_row);
5559 }
5560 }
5561 }
5562
5563 if (ShowSquares && Map.getViewSize() < 4)
5564 {
5565 if(scr->stairx || scr->stairy)
5566 {
5567 int32_t x1 = scr->stairx+edge_xoff;
5568 int32_t y1 = scr->stairy+edge_yoff;
5569 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,vc(14));
5570 }
5571
5572 if(scr->warparrivalx || scr->warparrivaly)
5573 {
5574 int32_t x1 = scr->warparrivalx +edge_xoff;
5575 int32_t y1 = scr->warparrivaly +edge_yoff;
5576 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,vc(10));
5577 }
5578
5579 for(int32_t i=0; i<4; i++) if(scr->warpreturnx[i] || scr->warpreturny[i])
5580 {
5581 int32_t x1 = scr->warpreturnx[i]+edge_xoff;
5582 int32_t y1 = scr->warpreturny[i]+edge_yoff;
5583 int32_t clr = vc(9);
5584
5585 if(FlashWarpSquare==i)
5586 {
5587 if(!FlashWarpClk)
5588 FlashWarpSquare=-1;
5589 else if(!(--FlashWarpClk%3))
5590 clr = vc(15);
5591 }
5592
5593 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,clr);
5594 }
5595 }
5596
5597 if(ShowFFCs)
5598 {
5599 mapscr* ffscr = prv_mode ? Map.get_prvscr() : scr;
5600 int num_ffcs = ffscr->numFFC();
5601 for(int32_t i=num_ffcs-1; i>=0; i--)
5602 {
5603 ffcdata& ff = ffscr->ffcs[i];
5604 if(ff.data !=0 && (ff.layer >= CurrentLayer || (!CurrentLayer && ff.layer < 0) || (ff.flags&ffc_overlay)))
5605 {
5606 auto x = ff.x+edge_xoff;
5607 auto y = ff.y+edge_yoff;
5608 safe_rect(mapscreenbmp, x+0, y+0, x+ff.txsz*16-1, y+ff.tysz*16-1, vc(12));
5609 }
5610 }
5611 }
5612
5613 if(num_screens_to_draw == 1 && !(Flags&cDEBUG) && pixeldb==1)
5614 {
5615 for(int32_t j=168; j<176; j++)
5616 {
5617 for(int32_t i=0; i<256; i++)
5618 {
5619 if(((i^j)&1)==0)
5620 {
5621 putpixel(mapscreenbmp,edge_xoff+i,
5622 edge_yoff+j,vc(blackout_color));
5623 }
5624 }
5625 }
5626 }
5627
5628 int w = mapscreenbmp->w * mapscreen_single_scale;
5629 int h = mapscreenbmp->h * mapscreen_single_scale;
5630 stretch_blit(mapscreenbmp, screen_bitmap, 0, 0, mapscreenbmp->w, mapscreenbmp->h, mapscreen_x + xoff, mapscreen_y + yoff, w, h);
5631 }
5632
5633 static void draw_static_pos(const size_and_pos& sqr)
5634 {
5635 draw_static(screen, sqr.x, sqr.y, sqr.w, sqr.h);
5636 }
5637
5638 void draw_screenunit(int32_t unit, int32_t flags)
5639 {
5640 FONT* tfont = font;
5641 switch(unit)
5642 {
5643 case rSCRMAP:
5644 {
5645 mmap_mark_active();
5646
5647 size_and_pos *mini_sqr = &minimap;
5648 size_and_pos *real_mini_sqr = &real_minimap;
5649
5650 if(zoomed_minimap)
5651 {
5652 mini_sqr = &minimap_zoomed;
5653 real_mini_sqr = &real_minimap_zoomed;
5654 }
5655
5656 auto txt_x = real_mini_sqr->x+2+8*real_mini_sqr->xscale;
5657 auto txt_y = real_mini_sqr->y+2+8*real_mini_sqr->yscale;
5658
5659 rectfill(screen, mini_sqr->x-1, mini_sqr->y-2,mini_sqr->x+mini_sqr->w-1,mini_sqr->y+mini_sqr->h-1,jwin_pal[jcBOX]);
5660 if(zoomed_minimap)
5661 jwin_draw_frame(screen, mini_sqr->x-1, mini_sqr->y-2,mini_sqr->w,mini_sqr->h,FR_WIN);
5662 jwin_draw_minimap_frame(screen,real_mini_sqr->x,real_mini_sqr->y,real_mini_sqr->tw(), real_mini_sqr->th(), real_mini_sqr->xscale, FR_DEEP);
5663
5664 if(Map.getCurrMap()<Map.getMapCount())
5665 {
5666 for(int32_t i=0; i<MAPSCRS; i++)
5667 {
5668 auto& sqr = real_mini_sqr->subsquare(i);
5669
5670 if(Map.Scr(i)->valid&mVALID)
5671 {
5672 // Drawing is handled by mmap_draw.
5673 }
5674 else
5675 {
5676 if (InvalidBG == 2)
5677 {
5678 draw_checkerboard(screen, sqr.x, sqr.y, sqr.w);
5679 }
5680 else if (InvalidBG == 1)
5681 {
5682 draw_static_pos(sqr);
5683 }
5684 else
5685 {
5686 int32_t offs = 2*(sqr.w/9);
5687 draw_x(screen, sqr.x+offs, sqr.y+offs, sqr.x+sqr.w-1-offs, sqr.y+sqr.h-1-offs, vc(15));
5688 }
5689 }
5690 }
5691
5692 int32_t s=Map.getCurrScr();
5693
5694 BITMAP* txtbmp = create_bitmap_ex(8,256,64);
5695 clear_bitmap(txtbmp);
5696 int txtscale = zoomed_minimap ? (is_compact ? 2 : 3) : 1;
5697 font = get_zc_font(font_lfont_l);
5698
5699 int32_t space = text_length(font, "255")+2, spc_s = text_length(font, "S")+2, spc_m = text_length(font, "M")+2;
5700 textprintf_disabled(txtbmp,font,0,0,jwin_pal[jcLIGHT],jwin_pal[jcMEDDARK],"M");
5701 static int map_shortcut_tooltip_id = ttip_register_id();
5702 ttip_install(map_shortcut_tooltip_id, "Prev map: ,\nNext map: .", txt_x, txt_y, 30, 20, txt_x, txt_y - 60);
5703
5704 textprintf_ex(txtbmp,font,spc_m,0,jwin_pal[jcBOXFG],jwin_pal[jcBOX],"%-3d",Map.getCurrMap()+1);
5705
5706 textprintf_disabled(txtbmp,font,spc_m+space,0,jwin_pal[jcLIGHT],jwin_pal[jcMEDDARK],"S");
5707 textprintf_ex(txtbmp,font,spc_m+space+spc_s,0,jwin_pal[jcBOXFG],jwin_pal[jcBOX],"0x%02X (%d)",s, s);
5708 masked_stretch_blit(txtbmp, screen, 0, 0, 256, 64, txt_x, txt_y, 256*txtscale, 64*txtscale);
5709 destroy_bitmap(txtbmp);
5710 }
5711 }
5712 break;
5713 case rMAP:
5714 {
5715 refresh_visible_screens();
5716 mapscreen_single_scale = (double)mapscreen_screenunit_scale / Map.getViewSize();
5717
5718 int num_combos_width = 16 * Map.getViewSize();
5719 int num_combos_height = 11 * Map.getViewSize();
5720
5721 if(CurrentLayer > 0 && !mapscreen_valid_layers[CurrentLayer-1])
5722 CurrentLayer = 0;
5723
5724 if (HighQualityScreenRendering)
5725 {
5726 int startxint = mapscreen_x+(showedges?int(16*mapscreen_single_scale):0);
5727 int startyint = mapscreen_y+(showedges?int(16*mapscreen_single_scale):0);
5728 int w = 256*mapscreen_screenunit_scale*Map.getViewSize();
5729 int h = 176*mapscreen_screenunit_scale*Map.getViewSize();
5730
5731 MapViewRTI* rti_map_view = mapview_get_rti();
5732 rti_map_view->flags = Flags;
5733 rti_map_view->set_transform({.x = startxint, .y = startyint, .xscale = (float)mapscreen_single_scale, .yscale = (float)mapscreen_single_scale});
5734 rti_map_view->set_size(w, h);
5735 rti_map_view->dirty = true;
5736 rti_map_view->freeze = false;
5737 // TODO: could be improved. This currently makes the transform dirty every frame.
5738 get_root_rti()->add_child_before(rti_map_view, get_screen_rti());
5739 }
5740
5741 // Since the screen renders over the map view when HQR is enabled, the screen rti needs to be transparent.
5742 // But not if HQR is off, that would cause bugs when drawing color 0.
5743 get_screen_rti()->transparency_index = HighQualityScreenRendering ? 0 : -1;
5744
5745 for (auto& vis_screen : visible_screens)
5746 {
5747 draw_screenunit_map_screen(vis_screen);
5748 }
5749
5750 if (showxypos_icon)
5751 {
5752 int x0 = showxypos_x + (showedges?16:0);
5753 int y0 = showxypos_y + (showedges?16:0);
5754 int x1 = x0 + showxypos_w - 1;
5755 int y1 = y0 + showxypos_h - 1;
5756 x0 *= mapscreen_single_scale;
5757 y0 *= mapscreen_single_scale;
5758 x1 *= mapscreen_single_scale;
5759 y1 *= mapscreen_single_scale;
5760 x0 += mapscreen_x;
5761 y0 += mapscreen_y;
5762 x1 += mapscreen_x;
5763 y1 += mapscreen_y;
5764
5765 if (showxypos_color == vc(15))
5766 safe_rect(screen, x0, y0, x1, y1, showxypos_color);
5767 else
5768 rectfill(screen, x0, y0, x1, y1, showxypos_color);
5769 }
5770
5771 if(showxypos_cursor_icon)
5772 {
5773 int x0 = showxypos_cursor_x + (showedges?16:0);
5774 int y0 = showxypos_cursor_y + (showedges?16:0);
5775 int x1 = x0 + showxypos_w - 1;
5776 int y1 = y0 + showxypos_h - 1;
5777 x0 *= mapscreen_single_scale;
5778 y0 *= mapscreen_single_scale;
5779 x1 *= mapscreen_single_scale;
5780 y1 *= mapscreen_single_scale;
5781 x0 += mapscreen_x;
5782 y0 += mapscreen_y;
5783 x1 += mapscreen_x;
5784 y1 += mapscreen_y;
5785 safe_rect(screen, x0, y0, x1, y1, showxypos_cursor_color);
5786 }
5787
5788 // Draw dithering over the edge/preview combos.
5789 if(showedges)
5790 {
5791 int tile_size = 16 * mapscreen_single_scale;
5792 int tiles_across = (16 * Map.getViewSize()) + 2;
5793 int bottom_row_y = (Map.getViewSize()*11 + 1) * tile_size;
5794 int right_col_x = (Map.getViewSize()*16 + 1) * tile_size;
5795
5796 //top preview
5797 for(int32_t j=0; j<tile_size; j++)
5798 {
5799 for(int32_t i=0; i<tiles_across * tile_size; i++)
5800 {
5801 if(((i^j)&1)==0)
5802 {
5803 putpixel(screen,mapscreen_x+i,mapscreen_y+j,vc(0));
5804 }
5805 }
5806 }
5807
5808 //bottom preview
5809 for(int32_t j = bottom_row_y; j < bottom_row_y + tile_size; j++)
5810 {
5811 for(int32_t i=0; i<tiles_across * tile_size; i++)
5812 {
5813 if(((i^j)&1)==0)
5814 {
5815 putpixel(screen,mapscreen_x+i,mapscreen_y+j,vc(0));
5816 }
5817 }
5818 }
5819
5820 //left preview
5821 for(int32_t j=tile_size; j<int32_t(192*mapscreen_screenunit_scale); j++)
5822 {
5823 for(int32_t i=0; i<16*mapscreen_single_scale; i++)
5824 {
5825 if(((i^j)&1)==0)
5826 {
5827 putpixel(screen,mapscreen_x+i,mapscreen_y+j,vc(0));
5828 }
5829 }
5830 }
5831
5832 //right preview
5833 for(int32_t j=tile_size; j<int32_t(192*mapscreen_screenunit_scale); j++)
5834 {
5835 for(int32_t i = right_col_x; i < right_col_x + tile_size; i++)
5836 {
5837 if(((i^j)&1)==0)
5838 {
5839 putpixel(screen,mapscreen_x+i,mapscreen_y+j,vc(0));
5840 }
5841 }
5842 }
5843 }
5844
5845 if(!(Flags&cDEBUG) && pixeldb==2)
5846 {
5847 for(int32_t j=int32_t(168*mapscreen_single_scale); j<int32_t(176*mapscreen_single_scale); j++)
5848 {
5849 for(int32_t i=0; i<int32_t(256*mapscreen_single_scale); i++)
5850 {
5851
5852 if(((i^j)&1)==0)
5853 {
5854 putpixel(screen,int32_t(mapscreen_x+(showedges?(16*mapscreen_single_scale):0)+i),
5855 int32_t(mapscreen_y+(showedges?(16*mapscreen_single_scale):0)+j),vc(blackout_color));
5856 }
5857 }
5858 }
5859 }
5860
5861 // TODO: This should move to `zmap::draw` (and delete the current code there doing a similar thing).
5862 if (Map.isDark(Map.getCurrScr()) && Map.getViewSize() == 1)
5863 {
5864 if((Flags&cNEWDARK) && get_qr(qr_NEW_DARKROOM))
5865 {
5866 BITMAP* tmpDark = create_bitmap_ex(8,16*16,16*11);
5867 BITMAP* tmpDarkTrans = create_bitmap_ex(8,16*16,16*11);
5868 BITMAP* tmpbuf = create_bitmap_ex(8,
5869 mapscreen_single_scale*(256+(showedges?32:0)),
5870 mapscreen_single_scale*(176+(showedges?32:0)));
5871 BITMAP* tmpbuf2 = create_bitmap_ex(8,
5872 mapscreen_single_scale*(256+(showedges?32:0)),
5873 mapscreen_single_scale*(176+(showedges?32:0)));
5874 int32_t darkCol = zinit.darkcol;
5875 switch(darkCol) //special cases
5876 {
5877 case BLACK:
5878 darkCol = vc(0);
5879 break;
5880 case WHITE:
5881 darkCol = vc(15);
5882 break;
5883 }
5884 clear_to_color(tmpDark, darkCol);
5885 clear_to_color(tmpDarkTrans, darkCol);
5886 clear_bitmap(tmpbuf);
5887 clear_bitmap(tmpbuf2);
5888 //Handle torch combos
5889 color_map = trans_table2;
5890 Map.draw_darkness(tmpDark, tmpDarkTrans);
5891 //
5892 mapscr* tmp = Map.CurrScr();
5893 if(tmp->flags9 & fDARK_DITHER)
5894 {
5895 ditherblit(tmpDark, tmpDark, 0, zinit.dither_type, zinit.dither_arg);
5896 ditherblit(tmpDarkTrans, tmpDarkTrans, 0, zinit.dither_type, zinit.dither_arg);
5897 }
5898
5899 if(mapscreen_single_scale == 1)
5900 {
5901 blit(tmpDark, tmpbuf, 0, 0, (showedges?16:0), (showedges?16:0), 16*16, 16*11);
5902 blit(tmpDarkTrans, tmpbuf2, 0, 0, (showedges?16:0), (showedges?16:0), 16*16, 16*11);
5903 }
5904 else
5905 {
5906 stretch_blit(tmpDark, tmpbuf, 0, 0, 16*16, 16*11,
5907 (showedges?16:0)*mapscreen_single_scale, (showedges?16:0)*mapscreen_single_scale,
5908 (16*16)*mapscreen_single_scale, (16*11)*mapscreen_single_scale);
5909 stretch_blit(tmpDarkTrans, tmpbuf2, 0, 0, 16*16, 16*11,
5910 (showedges?16:0)*mapscreen_single_scale, (showedges?16:0)*mapscreen_single_scale,
5911 (16*16)*mapscreen_single_scale, (16*11)*mapscreen_single_scale);
5912 }
5913
5914 if(tmp->flags9 & fDARK_TRANS)
5915 {
5916 draw_trans_sprite(screen, tmpbuf, mapscreen_x, mapscreen_y);
5917 }
5918 else
5919 {
5920 masked_blit(tmpbuf,screen,0,0,mapscreen_x,mapscreen_y,tmpbuf->w,tmpbuf->h);
5921 }
5922 draw_trans_sprite(screen, tmpbuf2, mapscreen_x, mapscreen_y);
5923 color_map = trans_table;
5924 //
5925 destroy_bitmap(tmpDark);
5926 destroy_bitmap(tmpDarkTrans);
5927 destroy_bitmap(tmpbuf);
5928 destroy_bitmap(tmpbuf2);
5929 }
5930 else if(!(Flags&cNODARK))
5931 {
5932 for(int32_t j=0; j<80*mapscreen_single_scale; j++)
5933 {
5934 for(int32_t i=0; i<(80*mapscreen_single_scale)-j; i++)
5935 {
5936 if(((i^j)&1)==0)
5937 {
5938 putpixel(screen,int32_t(mapscreen_x+(showedges?(16*mapscreen_single_scale):0))+i,
5939 int32_t(mapscreen_y+(showedges?(16*mapscreen_single_scale):0)+j),vc(blackout_color));
5940 }
5941 }
5942 }
5943 }
5944 }
5945
5946 double startx=mapscreen_x+(showedges?(16*mapscreen_single_scale):0);
5947 double starty=mapscreen_y+(showedges?(16*mapscreen_single_scale):0);
5948 bool inrect = isinRect(gui_mouse_x(),gui_mouse_y(),startx,starty,(startx+(256*mapscreen_screenunit_scale)-1),(starty+(176*mapscreen_screenunit_scale)-1));
5949
5950 if(!(flags&rNOCURSOR) && ((ComboBrush && !ComboBrushPause)||draw_mode==dm_alias) && inrect)
5951 {
5952 int mgridscale=16*mapscreen_single_scale;
5953 if(allowHideMouse)
5954 {
5955 if(arrowcursor)
5956 {
5957 arrowcursor = false;
5958 MouseSprite::set(ZQM_BLANK);
5959 }
5960 }
5961 else if(!arrowcursor)
5962 {
5963 arrowcursor = true;
5964 MouseSprite::set(ZQM_NORMAL);
5965 }
5966 ComboPosition pos = get_mapscreen_mouse_combo_pos();
5967 int32_t mx = pos.x * 16 * mapscreen_single_scale;
5968 int32_t my = pos.y * 16 * mapscreen_single_scale;
5969
5970 clear_bitmap(brushscreen);
5971 int32_t tempbw=BrushWidth;
5972 int32_t tempbh=BrushHeight;
5973
5974 if(draw_mode==dm_alias)
5975 {
5976 BrushWidth = combo_aliases[combo_apos].width+1;
5977 BrushHeight = combo_aliases[combo_apos].height+1;
5978 }
5979 else if(draw_mode == dm_cpool)
5980 {
5981 BrushWidth = BrushHeight = 1;
5982 combo_pool const& pool = combo_pools[combo_pool_pos];
5983 if(pool.valid())
5984 {
5985 int32_t cid = Combo;
5986 int8_t cset = CSet;
5987 pool.get_w_wrap(cid,cset,cpoolbrush_index/16); //divide to reduce speed
5988 put_combo(brushbmp,0,0,cid,cset,Flags&(cFLAGS|cWALK),0);
5989 }
5990 else clear_bitmap(brushbmp);
5991 }
5992 else if (draw_mode == dm_auto)
5993 {
5994 BrushWidth = BrushHeight = 1;
5995 }
5996
5997 stretch_blit(brushbmp, brushscreen, 0, 0, BrushWidth*16, BrushHeight*16, 0, 0, BrushWidth*mgridscale, BrushHeight*mgridscale);
5998 int float_offx = 0;
5999 int float_offy = 0;
6000
6001 if(FloatBrush)
6002 {
6003 float_offx = -SHADOW_DEPTH*mapscreen_single_scale;
6004 float_offy = -SHADOW_DEPTH*mapscreen_single_scale;
6005
6006 //shadow
6007 for(int x = 0; x < SHADOW_DEPTH*mapscreen_single_scale; ++x)
6008 for(int y = 0; y < (BrushHeight*mgridscale) + (SHADOW_DEPTH*mapscreen_single_scale); ++y)
6009 {
6010 if((((x^y)&1)==1) && y < 12*mgridscale)
6011 putpixel(brushscreen,x+(BrushWidth*mgridscale),y,vc(0));
6012 }
6013
6014 for(int x = 0; x < BrushWidth*mgridscale; ++x)
6015 for(int y = 0; y < SHADOW_DEPTH*mapscreen_single_scale; ++y)
6016 {
6017 if((((x^y)&1)==1) && x<16*mgridscale)
6018 putpixel(brushscreen,x,y+(BrushHeight*mgridscale),vc(0));
6019 }
6020 }
6021
6022 if(draw_mode==dm_alias)
6023 {
6024 combo_alias *combo = &combo_aliases[combo_apos];
6025
6026 if(BrushWidth > 1 && (alias_origin & 1)) //right-align
6027 float_offx -= (BrushWidth - 1) * mgridscale;
6028
6029 if(BrushHeight > 1 && (alias_origin & 2)) //bottom-align
6030 float_offy -= (BrushHeight - 1) * mgridscale;
6031 }
6032
6033 int bx = mapscreen_x + mx + float_offx + (showedges?(16*mapscreen_single_scale):0);
6034 int by = mapscreen_y + my + float_offy + (showedges?(16*mapscreen_single_scale):0);
6035 masked_blit(brushscreen, screen, 0, 0, bx, by, 16*mgridscale, 11*mgridscale);
6036 BrushWidth=tempbw;
6037 BrushHeight=tempbh;
6038 }
6039 else
6040 {
6041 if(!arrowcursor)
6042 {
6043 MouseSprite::set(ZQM_NORMAL);
6044 arrowcursor = true;
6045 }
6046 }
6047
6048 int startxint = mapscreen_x+(showedges?int(16*mapscreen_single_scale):0);
6049 int startyint = mapscreen_y+(showedges?int(16*mapscreen_single_scale):0);
6050 int endxint = startx + 256*mapscreen_screenunit_scale - 1;
6051 int endyint = starty + 176*mapscreen_screenunit_scale - 1;
6052 set_clip_rect(screen,startxint,startyint,endxint,endyint);
6053
6054 if(ShowGrid)
6055 {
6056 int w = num_combos_width;
6057 int h = num_combos_height;
6058 double tile_size = 16.0 / Map.getViewSize() * mapscreen_screenunit_scale;
6059
6060 if(showedges)
6061 {
6062 w += 2;
6063 h += 2;
6064 }
6065
6066 for (int x = 1; x < w; x++)
6067 {
6068 vline(screen, mapscreen_x + x*tile_size, mapscreen_y, mapscreen_y + (h*tile_size)-1, vc(GridColor));
6069 }
6070
6071 for (int y = 1; y < h; y++)
6072 {
6073 hline(screen, mapscreen_x, mapscreen_y + y*tile_size, mapscreen_x + (w*tile_size)-1, vc(GridColor));
6074 }
6075 }
6076
6077 if(ShowScreenGrid)
6078 {
6079 int w = num_combos_width;
6080 int h = num_combos_height;
6081 double tile_size = 16.0 / Map.getViewSize() * mapscreen_screenunit_scale;
6082 int startx = mapscreen_x + (showedges ? (16 * mapscreen_single_scale) : 0);
6083 int starty = mapscreen_y + (showedges ? (16 * mapscreen_single_scale) : 0);
6084
6085 if(showedges)
6086 {
6087 w += 1;
6088 h += 1;
6089 }
6090
6091 int color = (GridColor+8)%16;
6092
6093 for (int x = 16; x < w; x+=16)
6094 {
6095 vline(screen, startx + x*tile_size, mapscreen_y, starty + (h*tile_size)-1, vc(color));
6096 }
6097
6098 for (int y = 11; y < h; y+=11)
6099 {
6100 hline(screen, startx, starty + y*tile_size, startx + (w*tile_size)-1, vc(color));
6101 }
6102 }
6103
6104 // Draw a rect around regions.
6105 if (ShowRegionGrid && Map.getViewSize() > 1)
6106 {
6107 for (const auto& region_description : Map.get_region_descriptions())
6108 {
6109 int sx = region_description.screen % 16;
6110 int sy = region_description.screen / 16;
6111 int sw = region_description.w;
6112 int sh = region_description.h;
6113
6114 int mw = 256 * mapscreen_single_scale;
6115 int mh = 176 * mapscreen_single_scale;
6116 int mx = sx - (Map.getViewScr() % 16);
6117 int my = sy - (Map.getViewScr() / 16);
6118 int x0 = mapscreen_x + (showedges ? (16 * mapscreen_single_scale) : 0) + mx * mw;
6119 int y0 = mapscreen_y + (showedges ? (16 * mapscreen_single_scale) : 0) + my * mh;
6120 rect(screen, x0+2, y0+2, x0 + mw*sw - 2, y0 + mh*sh - 2, vc(1));
6121 rect(screen, x0+1, y0+1, x0 + mw*sw - 1, y0 + mh*sh - 1, vc(15));
6122 rect(screen, x0, y0, x0 + mw*sw, y0 + mh*sh, vc(1));
6123 }
6124 }
6125
6126 // Draw a black-yellow-black rect around the currently selected screen.
6127 if (ShowCurScreenOutline && Map.getViewSize() > 1)
6128 {
6129 int mw = 256 * mapscreen_single_scale;
6130 int mh = 176 * mapscreen_single_scale;
6131 int mx = (Map.getCurrScr() % 16) - (Map.getViewScr() % 16);
6132 int my = (Map.getCurrScr() / 16) - (Map.getViewScr() / 16);
6133 int x0 = mapscreen_x + (showedges ? (16 * mapscreen_single_scale) : 0) + mx * mw;
6134 int y0 = mapscreen_y + (showedges ? (16 * mapscreen_single_scale) : 0) + my * mh;
6135 dotted_rect(screen, x0+2, y0+2, x0 + mw - 2, y0 + mh - 2, vc(1), vc(0));
6136 rect(screen, x0+1, y0+1, x0 + mw - 1, y0 + mh - 1, vc(14));
6137 dotted_rect(screen, x0, y0, x0 + mw, y0 + mh, vc(1), vc(0));
6138 }
6139
6140 clear_clip_rect(screen);
6141
6142 // Map tabs
6143 font = get_custom_font(CFONT_GUI);
6144
6145 map_page[current_mappage].map=Map.getCurrMap();
6146 map_page[current_mappage].screen=Map.getCurrScr();
6147
6148 for(int32_t btn=0; btn<mappage_count; ++btn)
6149 {
6150 char tbuf[15];
6151 sprintf(tbuf, "%d:%02X", map_page[btn].map+1, map_page[btn].screen);
6152 draw_layer_button(screen,map_page_bar[btn].x, map_page_bar[btn].y, map_page_bar[btn].w, map_page_bar[btn].h,tbuf,(btn==current_mappage?D_SELECTED:0));
6153 }
6154 }
6155 break;
6156 case rCOMBOS:
6157 {
6158 auto real_h = combolist_window.h;
6159 jwin_draw_frame(screen,combolist_window.x,combolist_window.y,combolist_window.w,real_h, FR_WIN);
6160 rectfill(screen,combolist_window.x+2,combolist_window.y+2,combolist_window.x+combolist_window.w-3,combolist_window.y+real_h-3,jwin_pal[jcBOX]);
6161
6162 //Scrollers
6163 for(int32_t c = 0; c < num_combo_cols; ++c)
6164 {
6165 auto& pos = combolistscrollers[c];
6166
6167 { //Scroll up
6168 auto& p = pos.subsquare(0);
6169 jwin_draw_frame(screen,p.x,p.y,p.w,p.h,FR_ETCHED);
6170
6171 for(int32_t i=0; i<3; i++)
6172 {
6173 hline(screen, p.x+5-i, p.y+4+i, p.x+5+i, jwin_pal[jcBOXFG]);
6174 }
6175 }
6176
6177 { //Scroll down
6178 auto& p = pos.subsquare(1);
6179 jwin_draw_frame(screen,p.x,p.y,p.w,p.h,FR_ETCHED);
6180
6181 for(int32_t i=0; i<3; i++)
6182 {
6183 hline(screen,p.x+5-i,p.y+6-i, p.x+5+i, jwin_pal[jcBOXFG]);
6184 }
6185 }
6186 }
6187
6188 if(draw_mode==dm_alias)
6189 {
6190 if(LinkedScroll)
6191 {
6192 int tmp = current_comboalist;
6193 for(int q = tmp-1; q >= 0; --q)
6194 {
6195 combo_alistpos[q] = combo_alistpos[q+1]-(comboaliaslist[q].w*comboaliaslist[q].h);
6196 if(combo_alistpos[q] < 0)
6197 {
6198 tmp = 0;
6199 combo_alistpos[0] = 0;
6200 break;
6201 }
6202 }
6203 for(int q = tmp+1; q < num_combo_cols; ++q)
6204 combo_alistpos[q] = combo_alistpos[q-1]+(comboaliaslist[q-1].w*comboaliaslist[q-1].h);
6205 for(int q = 0; q < num_combo_cols; ++q)
6206 if(combo_apos >= combo_alistpos[q] && combo_apos < combo_alistpos[q] + (comboaliaslist[q].w*comboaliaslist[q].h))
6207 {
6208 current_comboalist = q;
6209 break;
6210 }
6211 }
6212 for(int32_t c = 0; c < num_combo_cols; ++c)
6213 {
6214 auto& pos = comboaliaslist[c];
6215 rectfill(screen,pos.x,pos.y,pos.x+(pos.w*pos.xscale)-1,pos.y+(pos.h*pos.yscale)-1,0);
6216 jwin_draw_frame(screen,pos.x-2,pos.y-2,(pos.w*pos.xscale)+4,(pos.h*pos.yscale)+4,FR_DEEP);
6217 }
6218
6219 auto& prev = comboalias_preview;
6220 jwin_draw_frame(screen, prev.x-2, prev.y-2, prev.w+4, prev.h+4,FR_DEEP);
6221
6222 BITMAP *prv = create_bitmap_ex(8,64,64);
6223 clear_bitmap(prv);
6224 int32_t scalefactor = 1;
6225
6226 for(int32_t j=0; j<num_combo_cols; ++j)
6227 {
6228 auto per_page = (comboaliaslist[j].w * comboaliaslist[j].h);
6229 if(combo_alistpos[j] + per_page >= MAXCOMBOALIASES)
6230 combo_alistpos[j] = MAXCOMBOALIASES-per_page;
6231 auto& col = comboaliaslist[j];
6232 for(int32_t i=0; i<(comboaliaslist[j].w*comboaliaslist[j].h); i++)
6233 {
6234 draw_combo_alias_thumbnail(screen, &combo_aliases[combo_alistpos[j]+i],
6235 (i%col.w)*col.xscale+col.x, (i/col.w)*col.yscale+col.y, col.xscale/16);
6236 }
6237
6238 if((combo_aliases[combo_apos].width>7)||(combo_aliases[combo_apos].height>7))
6239 {
6240 scalefactor=4;
6241 }
6242 else if((combo_aliases[combo_apos].width>3)||(combo_aliases[combo_apos].height>3))
6243 {
6244 scalefactor=2;
6245 }
6246
6247
6248 if(j==current_comboalist)
6249 {
6250 stretch_blit(brushbmp, prv, 0,0,scalefactor*64,zc_min(scalefactor*64,176),0,0,64,scalefactor==4?44:64);
6251 blit(prv,screen,0,0,comboalias_preview.x,comboalias_preview.y,comboalias_preview.w,comboalias_preview.h);
6252
6253 int32_t rect_pos=combo_apos-combo_alistpos[current_comboalist];
6254
6255 if((rect_pos>=0)&&(rect_pos<(combo_alistpos[current_comboalist]+(col.w*col.h))))
6256 {
6257 int selw = col.xscale;
6258 int selh = col.yscale;
6259 int x1 = (rect_pos&(col.w-1))*col.xscale+col.x;
6260 int y1 = (rect_pos/col.w)*col.yscale+col.y;
6261 safe_rect(screen,x1,y1,x1+selw-1,y1+selh-1,vc(CmbCursorCol),2);
6262 }
6263 }
6264 }
6265
6266 destroy_bitmap(prv);
6267 }
6268 else if(draw_mode==dm_cpool)
6269 {
6270 if(LinkedScroll)
6271 {
6272 int tmp = current_cpoollist;
6273 for(int q = tmp-1; q >= 0; --q)
6274 {
6275 combo_pool_listpos[q] = combo_pool_listpos[q+1]-(comboaliaslist[q].w*comboaliaslist[q].h);
6276 if(combo_pool_listpos[q] < 0)
6277 {
6278 tmp = 0;
6279 combo_pool_listpos[0] = 0;
6280 break;
6281 }
6282 }
6283 for(int q = tmp+1; q < num_combo_cols; ++q)
6284 combo_pool_listpos[q] = combo_pool_listpos[q-1]+(comboaliaslist[q-1].w*comboaliaslist[q-1].h);
6285 for(int q = 0; q < num_combo_cols; ++q)
6286 if(combo_pool_pos >= combo_pool_listpos[q] && combo_pool_pos < combo_pool_listpos[q] + (comboaliaslist[q].w*comboaliaslist[q].h))
6287 {
6288 current_cpoollist = q;
6289 break;
6290 }
6291 }
6292 for(int32_t c = 0; c < num_combo_cols; ++c)
6293 {
6294 auto& pos = comboaliaslist[c];
6295 rectfill(screen,pos.x,pos.y,pos.x+(pos.w*pos.xscale)-1,pos.y+(pos.h*pos.yscale)-1,0);
6296 jwin_draw_frame(screen,pos.x-2,pos.y-2,(pos.w*comboaliaslist[c].xscale)+4,(pos.h*comboaliaslist[c].yscale)+4,FR_DEEP);
6297 }
6298
6299 for (int32_t j = 0; j < num_combo_cols; ++j) //the actual panes
6300 {
6301 auto per_page = (comboaliaslist[j].w * comboaliaslist[j].h);
6302 if(combo_pool_listpos[j] + per_page >= MAXCOMBOPOOLS)
6303 combo_pool_listpos[j] = MAXCOMBOPOOLS-per_page;
6304 for(int32_t i=0; i<(comboaliaslist[j].w*comboaliaslist[j].h); i++)
6305 {
6306 int32_t cid=-1; int8_t cs=CSet;
6307 combo_pool const& cp = combo_pools[combo_pool_listpos[j]+i];
6308
6309 auto& list = comboaliaslist[j];
6310 if(cp.get_w(cid,cs,0) && !combobuf[cid].tile)
6311 {
6312 cid = -1; //no tile to draw
6313 }
6314 auto cx = (i%list.w)*list.xscale+list.x;
6315 auto cy = (i/list.w)*list.yscale+list.y;
6316 put_combo(screen,cx,cy,cid,cs,Flags&(cFLAGS|cWALK),0,list.xscale/16);
6317 }
6318 }
6319 int32_t rect_pos=combo_pool_pos-combo_pool_listpos[current_cpoollist];
6320
6321 if((rect_pos>=0)&&(rect_pos<(combo_pool_listpos[current_cpoollist]+(comboaliaslist[current_cpoollist].w*comboaliaslist[current_cpoollist].h))))
6322 {
6323 int selw = comboaliaslist[current_cpoollist].xscale;
6324 int selh = comboaliaslist[current_cpoollist].yscale;
6325 int x1 = (rect_pos&(comboaliaslist[current_cpoollist].w-1))*comboaliaslist[current_cpoollist].xscale+comboaliaslist[current_cpoollist].x;
6326 int y1 = (rect_pos/comboaliaslist[current_cpoollist].w)*comboaliaslist[current_cpoollist].yscale+comboaliaslist[current_cpoollist].y;
6327 safe_rect(screen,x1,y1,x1+selw-1,y1+selh-1,vc(CmbCursorCol),2);
6328 }
6329
6330 //Handle Preview
6331 combo_pool const& cpool = combo_pools[combo_pool_pos];
6332
6333 int32_t cid; int8_t cs;
6334 size_t total = weighted_cpool ? cpool.getTotalWeight() : cpool.combos.size();
6335 size_t ind = 0;
6336 size_t indw = combopool_preview.w/16;
6337 size_t indh = combopool_preview.h/16;
6338 size_t rows = total ? vbound(total/indw,1,indh) : 0;
6339 if (is_compact)
6340 rows = vbound(rows, 1, 3);
6341 else
6342 rows = vbound(rows, 1, 4);
6343 size_t real_height = rows*16;
6344
6345 cpool_prev_visible = rows > 0;
6346 if(rows)
6347 {
6348 jwin_draw_frame(screen,combopool_preview.x-2,combopool_preview.y-2,
6349 combopool_preview.w+4,real_height+4,FR_DEEP);
6350 rectfill(screen,combopool_preview.x,combopool_preview.y,
6351 combopool_preview.x+combopool_preview.w-1,
6352 combopool_preview.y+real_height-1,vc(0));
6353 draw_text_button(screen,combopool_prevbtn.x,combopool_prevbtn.y,
6354 combopool_prevbtn.w,combopool_prevbtn.h,
6355 weighted_cpool ? "Weighted" : "Unweighted",vc(1),vc(14),0,true);
6356 if(!is_compact)
6357 textprintf_ex(screen,font,combopool_prevbtn.x+combopool_prevbtn.w+5,
6358 combopool_prevbtn.y,jwin_pal[jcBOXFG],-1,"Preview");
6359 for(auto y = 0; y < real_height; y += 16)
6360 {
6361 for(auto x = 0; x < combopool_preview.w; x += 16, ++ind)
6362 {
6363 auto nx = combopool_preview.x+x, ny = combopool_preview.y+y;
6364 if(ind < total)
6365 {
6366 cs = CSet;
6367 if(weighted_cpool
6368 ? cpool.get_w(cid,cs,ind)
6369 : cpool.get_ind(cid,cs,ind))
6370 {
6371 put_combo(screen,nx,ny,cid,cs,Flags&(cFLAGS|cWALK),0);
6372 continue;
6373 }
6374 }
6375 //No combo to display
6376 xout(screen, nx, ny, nx+15, ny+15, vc(15));
6377 }
6378 }
6379 }
6380 }
6381 else if (draw_mode == dm_auto)
6382 {
6383 if (LinkedScroll)
6384 {
6385 int tmp = current_cautolist;
6386 for (int q = tmp - 1; q >= 0; --q)
6387 {
6388 combo_auto_listpos[q] = combo_auto_listpos[q + 1] - (comboaliaslist[q].w * comboaliaslist[q].h);
6389 if (combo_auto_listpos[q] < 0)
6390 {
6391 tmp = 0;
6392 combo_auto_listpos[0] = 0;
6393 break;
6394 }
6395 }
6396 for (int q = tmp + 1; q < num_combo_cols; ++q)
6397 combo_auto_listpos[q] = combo_auto_listpos[q - 1] + (comboaliaslist[q - 1].w * comboaliaslist[q - 1].h);
6398 for (int q = 0; q < num_combo_cols; ++q)
6399 if (combo_auto_pos >= combo_auto_listpos[q] && combo_auto_pos < combo_auto_listpos[q] + (comboaliaslist[q].w * comboaliaslist[q].h))
6400 {
6401 current_cautolist = q;
6402 break;
6403 }
6404 }
6405 for (int32_t c = 0; c < num_combo_cols; ++c)
6406 {
6407 auto& pos = comboaliaslist[c];
6408 rectfill(screen, pos.x, pos.y, pos.x + (pos.w * pos.xscale) - 1, pos.y + (pos.h * pos.yscale) - 1, 0);
6409 jwin_draw_frame(screen, pos.x - 2, pos.y - 2, (pos.w * comboaliaslist[c].xscale) + 4, (pos.h * comboaliaslist[c].yscale) + 4, FR_DEEP);
6410 }
6411
6412 for (int32_t j = 0; j < num_combo_cols; ++j) //the actual panes
6413 {
6414 auto per_page = (comboaliaslist[j].w * comboaliaslist[j].h);
6415 if(combo_auto_listpos[j] + per_page >= MAXAUTOCOMBOS)
6416 combo_auto_listpos[j] = MAXAUTOCOMBOS-per_page;
6417 for (int32_t i = 0; i < (comboaliaslist[j].w * comboaliaslist[j].h); i++)
6418 {
6419 int32_t cid = -1; int8_t cs = CSet;
6420 combo_auto const& ca = combo_autos[combo_auto_listpos[j] + i];
6421
6422 auto& list = comboaliaslist[j];
6423 cid = ca.getDisplay();
6424 if (cid == 0)
6425 cid = -1;
6426 auto cx = (i % list.w) * list.xscale + list.x;
6427 auto cy = (i / list.w) * list.yscale + list.y;
6428 put_combo(screen, cx, cy, cid, cs, Flags & (cFLAGS | cWALK), 0, list.xscale / 16);
6429 put_autocombo_engravings(screen, ca, combo_auto_listpos[j] + i == combo_auto_pos, cx, cy, list.xscale / 16);
6430 }
6431 }
6432 int32_t rect_pos = combo_auto_pos - combo_auto_listpos[current_cautolist];
6433
6434 if ((rect_pos >= 0) && (rect_pos < (combo_auto_listpos[current_cautolist] + (comboaliaslist[current_cautolist].w * comboaliaslist[current_cautolist].h))))
6435 {
6436 int selw = comboaliaslist[current_cautolist].xscale;
6437 int selh = comboaliaslist[current_cautolist].yscale;
6438 int x1 = (rect_pos & (comboaliaslist[current_cautolist].w - 1)) * comboaliaslist[current_cautolist].xscale + comboaliaslist[current_cautolist].x;
6439 int y1 = (rect_pos / comboaliaslist[current_cautolist].w) * comboaliaslist[current_cautolist].yscale + comboaliaslist[current_cautolist].y;
6440 safe_rect(screen, x1, y1, x1 + selw - 1, y1 + selh - 1, vc(CmbCursorCol), 2);
6441
6442 combo_auto const& ca = combo_autos[combo_auto_pos];
6443 put_autocombo_engravings(screen, ca, true, x1, y1, selw / 16);
6444 }
6445 }
6446 else
6447 {
6448 if(LinkedScroll)
6449 {
6450 int tmp = current_combolist;
6451 for(int q = tmp-1; q >= 0; --q)
6452 {
6453 First[q] = First[q+1]-(combolist[q].w*combolist[q].h);
6454 if(First[q] < 0)
6455 {
6456 tmp = 0;
6457 First[0] = 0;
6458 break;
6459 }
6460 }
6461 for(int q = tmp+1; q < num_combo_cols; ++q)
6462 First[q] = First[q-1]+(combolist[q-1].w*combolist[q-1].h);
6463 for(int q = 0; q < num_combo_cols; ++q)
6464 if(Combo >= First[q] && Combo < First[q] + (combolist[q].w*combolist[q].h))
6465 {
6466 current_combolist = q;
6467 break;
6468 }
6469 }
6470 for(int32_t c = 0; c < num_combo_cols; ++c)
6471 {
6472 auto& pos = combolist[c];
6473 rectfill(screen,pos.x,pos.y,pos.x+(pos.w*pos.xscale)-1,pos.y+(pos.h*pos.yscale)-1,0);
6474 jwin_draw_frame(screen,pos.x-2,pos.y-2,(pos.w*pos.xscale)+4,(pos.h*pos.yscale)+4,FR_DEEP);
6475 }
6476
6477 int32_t drawmap, drawscr;
6478 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
6479 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
6480
6481 for(int32_t j=0; j<num_combo_cols; ++j)
6482 {
6483 auto per_page = (combolist[j].w * combolist[j].h);
6484 if(First[j] + per_page >= MAXCOMBOS)
6485 First[j] = MAXCOMBOS-per_page;
6486 for(int32_t i=0; i<(combolist[j].w*combolist[j].h); i++)
6487 {
6488 put_combo(screen,(i%combolist[j].w)*combolist[j].xscale+combolist[j].x,
6489 (i/combolist[j].w)*combolist[j].yscale+combolist[j].y,
6490 i+First[j],CSet,Flags&(cFLAGS|cWALK),0,combolist[j].xscale/16);
6491 }
6492 }
6493
6494 int32_t rect_pos=Combo-First[current_combolist];
6495
6496 if((rect_pos>=0)&&(rect_pos<(combo_pool_listpos[current_combolist]+(combolist[current_combolist].w*combolist[current_combolist].h))))
6497 {
6498 int selw = (AutoBrush?BrushWidth:1)*combolist[current_combolist].xscale;
6499 int selh = (AutoBrush?BrushHeight:1)*combolist[current_combolist].yscale;
6500 int x1 = (rect_pos&(combolist[current_combolist].w-1))*combolist[current_combolist].xscale+combolist[current_combolist].x;
6501 int y1 = (rect_pos/combolist[current_combolist].w)*combolist[current_combolist].yscale+combolist[current_combolist].y;
6502 safe_rect(screen,x1,y1,x1+selw-1,y1+selh-1,vc(CmbCursorCol),2);
6503 }
6504 }
6505 }
6506 break;
6507 case rCOMBO:
6508 {
6509 int32_t drawmap, drawscr;
6510 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
6511 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
6512
6513 // Combo preview
6514 int32_t cid = Combo; int8_t cs = CSet;
6515 if(draw_mode == dm_alias)
6516 {
6517 cid = combo_aliases[combo_apos].combos[0];
6518 cs = wrap(combo_aliases[combo_apos].csets[0]+alias_cset_mod, 0, 13);
6519 }
6520 else if(draw_mode == dm_cpool)
6521 {
6522 combo_pool const& cpool = combo_pools[combo_pool_pos];
6523 cid = 0;
6524 cpool.get_w(cid,cs,0);
6525 }
6526 else if (draw_mode == dm_auto)
6527 {
6528 combo_auto const& cauto = combo_autos[combo_auto_pos];
6529 cid = cauto.getDisplay();
6530 }
6531 static BITMAP *combo_preview_bmp=create_bitmap_ex(8,32,32);
6532 static BITMAP *cycle_preview_bmp=create_bitmap_ex(8,32,32);
6533 // Combo
6534 put_combo(combo_preview_bmp,0,0,cid,cs,Flags&(cFLAGS|cWALK),0);
6535 jwin_draw_frame(screen,combo_preview.x-2,combo_preview.y-2,combo_preview.w+4,combo_preview.h+4, FR_DEEP);
6536 stretch_blit(combo_preview_bmp, screen, 0, 0, 16, 16, combo_preview.x, combo_preview.y, combo_preview.w, combo_preview.h);
6537
6538 comboprev_buf[0] = 0;
6539 comboprev_buf2[0] = 0;
6540 if(draw_mode == dm_cpool)
6541 {
6542 sprintf(comboprev_buf,"Pool: %d\nCSet: %d",combo_pool_pos,CSet);
6543 int x = combo_preview_text1.x+(combo_preview_text1.w*combo_preview_text1.xscale);
6544 textbox_out(screen,txfont,x,combo_preview_text1.y,jwin_pal[jcBOXFG],jwin_pal[jcBOX],comboprev_buf,2,&combo_preview_text1);
6545 }
6546 else if (draw_mode == dm_auto)
6547 {
6548 GUI::ListData ac_types = GUI::ZCListData::autocombotypes();
6549 std::string type_name = ac_types.findText(combo_autos[combo_auto_pos].getType());
6550 if (is_compact)
6551 sprintf(comboprev_buf, "AC: %d CS: %d\n%s", combo_auto_pos, CSet, type_name.c_str());
6552 else
6553 sprintf(comboprev_buf, "Auto: %d CSet: %d\n%s\nEntries: %d", combo_auto_pos, CSet, type_name.c_str(), int32_t(combo_autos[combo_auto_pos].combos.size()));
6554 int x = combo_preview_text1.x + (combo_preview_text1.w * combo_preview_text1.xscale);
6555 textbox_out(screen, txfont, x, combo_preview_text1.y, jwin_pal[jcBOXFG], jwin_pal[jcBOX], comboprev_buf, 2, &combo_preview_text1);
6556 }
6557 else if(draw_mode != dm_alias)
6558 {
6559 int x = combo_preview_text1.x+(combo_preview_text1.w*combo_preview_text1.xscale);
6560
6561 char shortbuf[512];
6562 char buf[256];
6563 strcpy(buf,combo_class_buf[combobuf[Combo].type].name);
6564 sprintf(comboprev_buf,"Combo: %d\nCSet: %d\n%s",Combo,CSet,buf);
6565 int ind = strlen(buf)-1;
6566 int x2 = x;
6567 if(x2 - text_length(txfont, buf) <= combolist_window.x)
6568 {
6569 auto dotlen = text_length(txfont, "..");
6570 x2 -= dotlen;
6571 while(x2 - text_length(txfont, buf) <= combolist_window.x)
6572 {
6573 if(ind < 0) break;
6574 buf[ind--] = '\0';
6575 }
6576 while(ind >= 0 && buf[ind] == ' ')
6577 buf[ind--] = 0; //trim spaces
6578 strcat(buf, "..");
6579 }
6580
6581 if(is_compact)
6582 {
6583 char b2[256];
6584 sprintf(b2, "Combo %d CS %d", Combo, CSet);
6585 if(x-text_length(txfont, b2) <= combolist_window.x)
6586 sprintf(b2, "Cmb %d CS %d", Combo, CSet);
6587 sprintf(shortbuf,"%s\n%s",b2,buf);
6588 }
6589 else sprintf(shortbuf,"Combo: %d\nCSet: %d\n%s",Combo,CSet,buf);
6590 textbox_out(screen,txfont,x,combo_preview_text1.y,jwin_pal[jcBOXFG],jwin_pal[jcBOX],shortbuf,2,&combo_preview_text1);
6591 }
6592
6593 // Cycle
6594 if(!is_compact)
6595 {
6596 int32_t NextCombo = combobuf[Combo].nextcombo;
6597 int32_t NextCSet = combobuf[Combo].nextcset;
6598 if(combobuf[Combo].animflags & AF_CYCLEUNDERCOMBO)
6599 {
6600 mapscr* scr = Map.CurrScr();
6601 NextCombo = scr->undercombo;
6602 NextCSet = scr->undercset;
6603 }
6604 if(combobuf[Combo].animflags & AF_CYCLENOCSET)
6605 NextCSet = CSet;
6606 bool normal_dm = draw_mode != dm_alias && draw_mode != dm_cpool && draw_mode != dm_auto;
6607 jwin_draw_frame(screen,combo_preview2.x-2,combo_preview2.y-2,combo_preview2.w+4,combo_preview2.h+4, FR_DEEP);
6608 if(NextCombo>0 && normal_dm)
6609 {
6610 put_combo(cycle_preview_bmp,0,0,NextCombo,NextCSet,Flags&(cFLAGS|cWALK),0);
6611
6612 if(Flags&cWALK) put_walkflags(cycle_preview_bmp,0,0,NextCombo,0);
6613
6614 if(Flags&cFLAGS) put_flags(cycle_preview_bmp,0,0,NextCombo,0,cFLAGS,0);
6615
6616 stretch_blit(cycle_preview_bmp, screen, 0, 0, 16, 16, combo_preview2.x, combo_preview2.y, combo_preview2.w, combo_preview2.h);
6617 }
6618 else
6619 {
6620 if (InvalidBG == 2)
6621 {
6622 draw_checkerboard(screen, combo_preview2.x, combo_preview2.y, 32);
6623 }
6624 else if(InvalidBG == 1)
6625 {
6626 draw_static_pos(combo_preview2);
6627 }
6628 else
6629 {
6630 rectfill(screen, combo_preview2.x,combo_preview2.y, combo_preview2.x+32,combo_preview2.y+combo_preview2.h,vc(0));
6631 safe_rect(screen, combo_preview2.x,combo_preview2.y, combo_preview2.x+32,combo_preview2.y+combo_preview2.h,vc(15));
6632 line(screen, combo_preview2.x,combo_preview2.y, combo_preview2.x+32,combo_preview2.y+combo_preview2.h,vc(15));
6633 line(screen, combo_preview2.x,combo_preview2.y+combo_preview2.h, combo_preview2.x+32,combo_preview2.y,vc(15));
6634 }
6635 }
6636
6637 if(normal_dm)
6638 {
6639 char shortbuf[512];
6640 char buf[256];
6641 strcpy(buf,combo_class_buf[combobuf[NextCombo].type].name);
6642 sprintf(comboprev_buf2, "Cycle: %d\nCSet: %d\n%s", NextCombo, NextCSet, buf);
6643 int ind = strlen(buf)-1;
6644 int x2 = combo_preview_text2.x;
6645 if(x2 + text_length(txfont, buf) > zq_screen_w-2)
6646 {
6647 auto dotlen = text_length(txfont, "..");
6648 x2 += dotlen;
6649 while(x2 + text_length(txfont, buf) > zq_screen_w-2)
6650 {
6651 if(ind < 0) break;
6652 buf[ind--] = '\0';
6653 }
6654 while(ind >= 0 && buf[ind] == ' ')
6655 buf[ind--] = 0; //trim spaces
6656 strcat(buf, "..");
6657 }
6658
6659 sprintf(shortbuf, "Cycle: %d\nCSet: %d\n%s", NextCombo, NextCSet, buf);
6660 textbox_out(screen,txfont,combo_preview_text2.x,combo_preview_text2.y,jwin_pal[jcBOXFG],jwin_pal[jcBOX],shortbuf,0,&combo_preview_text2);
6661 }
6662 }
6663
6664 font = get_zc_font(font_lfont_l);
6665 bool merged = is_compact ? compact_merged_combopane : large_merged_combopane;
6666 draw_text_button(screen,combo_merge_btn.x,combo_merge_btn.y,combo_merge_btn.w,combo_merge_btn.h,merged ? "<|>" : ">|<",vc(1),vc(14),0,true);
6667 }
6668 break;
6669 case rFAVORITES:
6670 {
6671 font = get_zc_font(font_lfont_l);
6672
6673 jwin_draw_frame(screen,favorites_window.x,favorites_window.y,favorites_window.w,favorites_window.h, FR_WIN);
6674 rectfill(screen,favorites_window.x+2,favorites_window.y+2,favorites_window.x+favorites_window.w-3,favorites_window.y+favorites_window.h-3,jwin_pal[jcBOX]);
6675 jwin_draw_frame(screen,favorites_list.x-2,favorites_list.y-2,(favorites_list.w*favorites_list.xscale)+4,(favorites_list.h*favorites_list.yscale)+4, FR_DEEP);
6676 rectfill(screen,favorites_list.x,favorites_list.y,favorites_list.x+(favorites_list.w*favorites_list.xscale)-1,favorites_list.y+(favorites_list.h*favorites_list.yscale)-1,jwin_pal[jcBOXFG]);
6677
6678 textprintf_ex(screen,get_zc_font(font_lfont_l),favorites_list.x-2,favorites_list.y-15,jwin_pal[jcBOXFG],-1,is_compact ? "Favorites" : "Favorite Combos");
6679 BITMAP* subb = create_bitmap_ex(8,16,16);
6680
6681 for(int32_t col=0; col<favorites_list.w; ++col)
6682 {
6683 for(int32_t row=0; row<favorites_list.h; ++row)
6684 {
6685 auto i = (row*FAVORITECOMBO_PER_ROW)+col+FAVORITECOMBO_PER_PAGE*FavoriteComboPage;
6686 auto& sqr = favorites_list.subsquare(col,row);
6687 if(i >= MAXFAVORITECOMBOS || favorite_combos[i]==-1)
6688 {
6689 if (InvalidBG == 2)
6690 {
6691 draw_checkerboard(screen, sqr.x, sqr.y, sqr.w);
6692 }
6693 else if(InvalidBG == 1)
6694 {
6695 draw_static_pos(sqr);
6696 }
6697 else
6698 {
6699 xout(screen, sqr.x, sqr.y, sqr.x+sqr.w-1, sqr.y+sqr.h-1, vc(15), vc(0));
6700 }
6701 }
6702 else
6703 {
6704 clear_bitmap(subb);
6705 bool repos = combotile_override_x < 0 && combotile_override_y < 0;
6706
6707 switch(favorite_combo_modes[i])
6708 {
6709 case dm_alias:
6710 draw_combo_alias_thumbnail(subb, &combo_aliases[favorite_combos[i]], 0, 0, 1);
6711 if (ShowFavoriteComboModes)
6712 put_engraving(subb, 0, 0, 0x3E, 1);
6713 break;
6714 case dm_cpool:
6715 {
6716 int32_t cid = -1; int8_t cs = CSet;
6717 combo_pool const& cp = combo_pools[favorite_combos[i]];
6718
6719 if (cp.get_w(cid, cs, 0) && !combobuf[cid].tile)
6720 cid = -1; //no tile to draw
6721 put_combo(subb, 0, 0, cid, cs, 0, 0);
6722 if (ShowFavoriteComboModes)
6723 put_engraving(subb, 0, 0, 0x3D, 1);
6724 break;
6725 }
6726 case dm_auto:
6727 {
6728 int32_t cid = -1; int8_t cs = CSet;
6729 combo_auto const& ca = combo_autos[favorite_combos[i]];
6730
6731 cid = ca.getDisplay();
6732 if (cid == 0)
6733 cid = -1;
6734 put_combo(subb, 0, 0, cid, cs, 0, 0);
6735 if (ShowFavoriteComboModes)
6736 put_engraving(subb, 0, 0, 0x3C, 1);
6737 break;
6738 }
6739 default:
6740 if (repos)
6741 {
6742 combotile_override_x = sqr.x + (sqr.w - 16) / 2;
6743 combotile_override_y = sqr.y + (sqr.h - 16) / 2;
6744 }
6745 put_combo(subb, 0, 0, favorite_combos[i], CSet, Flags & (cFLAGS | cWALK), 0);
6746 if (repos) combotile_override_x = combotile_override_y = -1;
6747 }
6748 stretch_blit(subb, screen, 0, 0, 16, 16, sqr.x, sqr.y, sqr.w, sqr.h);
6749 }
6750 }
6751 }
6752
6753 destroy_bitmap(subb);
6754
6755 bool zoomed = is_compact ? compact_zoomed_fav : large_zoomed_fav;
6756 if(!is_compact)
6757 textprintf_right_ex(screen, get_zc_font(font_lfont_l), favorites_pgleft.x - 2, favorites_pgleft.y, jwin_pal[jcBOXFG], -1, "%d/9", FavoriteComboPage + 1);
6758
6759 draw_text_button(screen, favorites_pgleft.x, favorites_pgleft.y, favorites_pgleft.w, favorites_pgleft.h, is_compact ? "<" : "<-", vc(1), vc(14), 0, true);
6760 draw_text_button(screen, favorites_pgright.x, favorites_pgright.y, favorites_pgright.w, favorites_pgright.h, is_compact ? ">" : "->", vc(1), vc(14), 0, true);
6761 draw_text_button(screen,favorites_zoombtn.x,favorites_zoombtn.y,favorites_zoombtn.w,favorites_zoombtn.h,zoomed ? "-" : "+",vc(1),vc(14),0,true);
6762 draw_text_button(screen,favorites_x.x,favorites_x.y,favorites_x.w,favorites_x.h,"X",vc(1),vc(14),0,true);
6763 draw_text_button(screen,favorites_infobtn.x,favorites_infobtn.y,favorites_infobtn.w,favorites_infobtn.h,"?",vc(1),vc(14),0,true);
6764 }
6765 break;
6766 case rCOMMANDS:
6767 {
6768 jwin_draw_frame(screen,commands_window.x,commands_window.y,commands_window.w,commands_window.h, FR_WIN);
6769 rectfill(screen,commands_window.x+2,commands_window.y+2,commands_window.x+commands_window.w-3,commands_window.y+commands_window.h-3,jwin_pal[jcBOX]);
6770 jwin_draw_frame(screen,commands_list.x-2,commands_list.y-2,(commands_list.w*commands_list.xscale)+4,(commands_list.h*commands_list.yscale)+4, FR_DEEP);
6771 rectfill(screen,commands_list.x,commands_list.y,commands_list.x+(commands_list.w*commands_list.xscale)-1,commands_list.y+(commands_list.h*commands_list.yscale)-1,jwin_pal[jcBOXFG]);
6772 font=get_custom_font(CFONT_FAVCMD);
6773
6774 for(int32_t cmd=0; cmd<(commands_list.w*commands_list.h); ++cmd)
6775 {
6776 uint hkey = favorite_commands[cmd];
6777 draw_layer_button(screen,
6778 (cmd%commands_list.w)*commands_list.xscale+commands_list.x,
6779 (cmd/commands_list.w)*commands_list.yscale+commands_list.y,
6780 commands_list.xscale,
6781 commands_list.yscale,
6782 get_hotkey_name(hkey),
6783 (selected_hotkey(hkey)?D_SELECTED:0) | (disabled_hotkey(hkey)?D_DISABLED:0));
6784 }
6785
6786 font = get_zc_font(font_lfont_l);
6787 if(commands_txt.x > 0)
6788 {
6789 gui_textout_ln(screen, get_zc_font(font_lfont_l), (ucc*)"Favorite Commands", commands_txt.x, commands_txt.y, jwin_pal[jcBOXFG], -1, 0);
6790 }
6791
6792 bool zoomed = is_compact ? compact_zoomed_cmd : large_zoomed_cmd;
6793 draw_text_button(screen,commands_zoombtn.x,commands_zoombtn.y,commands_zoombtn.w,commands_zoombtn.h,zoomed ? "-" : "+",vc(1),vc(14),0,true);
6794 draw_text_button(screen,commands_x.x,commands_x.y,commands_x.w,commands_x.h,"X",vc(1),vc(14),0,true);
6795 draw_text_button(screen,commands_infobtn.x,commands_infobtn.y,commands_infobtn.w,commands_infobtn.h,"?",vc(1),vc(14),0,true);
6796 }
6797 break;
6798 }
6799 font = tfont;
6800 }
6801
6802 bool pause_refresh = true;
6803 bool is_refreshing = false;
6804 11 void refresh(int32_t flags, bool update)
6805 {
6806
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(pause_refresh) return;
6807 static bool refreshing = false;
6808
6809 int num_screens_to_draw = Map.getViewSize();
6810
6811 bool earlyret = refreshing;
6812 is_refreshing = refreshing = true;
6813 //^ These prevent recursive calls from updating the screen early
6814
6815 bool zoom_delay = (zoomed_minimap && flags != rSCRMAP);
6816 if(zoom_delay)
6817 flags &= ~rSCRMAP;
6818
6819 if(flags&rCLEAR)
6820 {
6821 //magic pink = 0xED
6822 //system black = vc(0)
6823 //Clear a4 menu
6824 // clear_to_color(screen,jwin_pal[jcBOX]);
6825 clear_to_color(screen,0);
6826
6827 //Clears should refresh everything!
6828 flags |= rALL;
6829 }
6830
6831 if(flags&rSCRMAP)
6832 draw_screenunit(rSCRMAP,flags);
6833
6834 if(flags&rMAP)
6835 draw_screenunit(rMAP,flags);
6836
6837 if((flags&rCOMBOS) || (draw_mode == dm_cpool && (flags&rFAVORITES)))
6838 draw_screenunit(rCOMBOS,flags);
6839
6840 if(flags&(rCOMBO|rCOMBOS))
6841 draw_screenunit(rCOMBO,flags);
6842
6843 if(flags&rMENU)
6844 drawpanel();
6845
6846 if(flags&rFAVORITES)
6847 draw_screenunit(rFAVORITES,flags);
6848
6849 if(flags&rCOMMANDS)
6850 draw_screenunit(rCOMMANDS,flags);
6851
6852 FONT* tfont = font;
6853 font = get_custom_font(CFONT_GUI);
6854 jwin_draw_frame(screen,layer_panel.x,layer_panel.y,layer_panel.w,layer_panel.h,FR_DEEP);
6855 rectfill(screen,layer_panel.x,layer_panel.y,layer_panel.x+layer_panel.w-1,layer_panel.y+layer_panel.h-1,jwin_pal[jcBOX]);
6856
6857 for(int32_t i=0; i<=6; ++i)
6858 {
6859 char tbuf[15];
6860
6861 if (i>0 && mapscreen_valid_layers[i - 1] && num_screens_to_draw == 1)
6862 {
6863 if(is_compact)
6864 sprintf(tbuf, "%s%d %d:%02X", (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"", i, Map.CurrScr()->layermap[i-1], Map.CurrScr()->layerscreen[i-1]);
6865 else sprintf(tbuf, "%s%d (%d:%02X)", (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"", i, Map.CurrScr()->layermap[i-1], Map.CurrScr()->layerscreen[i-1]);
6866 }
6867 else
6868 {
6869 sprintf(tbuf, "%s%d", (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"", i);
6870 }
6871
6872 int32_t spacing_offs = is_compact ? 2 : 10;
6873 int32_t rx = (i * (layerpanel_buttonwidth+spacing_offs+layerpanel_checkbox_wid)) + layer_panel.x+(is_compact?2:6);
6874 int32_t ry = layer_panel.y;
6875 auto cbyofs = (layerpanel_buttonheight-layerpanel_checkbox_hei)/2;
6876 draw_layer_button(screen, rx, ry, layerpanel_buttonwidth, layerpanel_buttonheight, tbuf, CurrentLayer==i? D_SELECTED : ( i > 0 && !mapscreen_valid_layers[i-1]) ? D_DISABLED : 0);
6877 draw_checkbox(screen,rx+layerpanel_buttonwidth+1,ry+cbyofs,layerpanel_checkbox_wid,layerpanel_checkbox_hei,LayerMaskInt[i]!=0);
6878 }
6879
6880 font=tfont;
6881
6882 // } //if(true)
6883 if(zq_showpal)
6884 {
6885 for(int32_t i=0; i<256; i++)
6886 {
6887 rectfill(screen,((i&15)<<2)+256,((i>>4)<<2)+176,((i&15)<<2)+259,((i>>4)<<2)+179,i);
6888 }
6889 }
6890 { //Show top-left info
6891 size_t maxwid = (mapscreen_screenunit_scale*mapscreenbmp->w)-1;
6892 size_t maxhei = (mapscreen_screenunit_scale*mapscreenbmp->w);
6893 set_clip_rect(screen,mapscreen_x,mapscreen_y,mapscreen_x+maxwid-1,mapscreen_y+maxhei-1);
6894 FONT* showfont = get_custom_font(CFONT_INFO);
6895 int showfont_h = text_height(showfont);
6896 int32_t ypos = mapscreen_y;
6897 if(prv_mode)
6898 {
6899 textout_shadowed_ex(screen,showfont,"Preview Mode",0,ypos,vc(15),vc(0),infobg?vc(0):-1);
6900 ypos += showfont_h+1;
6901 if(prv_twon)
6902 {
6903 textprintf_shadowed_ex(screen,showfont,0,ypos,vc(15),vc(0),infobg?vc(0):-1,"T Warp=%d tics", Map.get_prvtime());
6904 ypos += showfont_h+1;
6905 }
6906 }
6907 if(ShowFPS)
6908 {
6909 textprintf_shadowed_ex(screen,showfont,0,ypos,vc(15),vc(0),infobg?vc(0):-1,"FPS: %3d",lastfps);
6910 ypos += showfont_h+1;
6911 }
6912
6913 if(ShowFFScripts && !prv_mode)
6914 {
6915 word num_ffcs = Map.CurrScr()->numFFC();
6916 for(word i=0; i< num_ffcs; i++)
6917 {
6918 if(ypos+showfont_h-1 > map_page_bar[0].y)
6919 break;
6920 if(Map.CurrScr()->ffcs[i].script && Map.CurrScr()->ffcs[i].data)
6921 {
6922 textout_shadowed_ex(screen, showfont, ffcmap[Map.CurrScr()->ffcs[i].script-1].scriptname.substr(0,300).c_str(),0,ypos,vc(showxypos_ffc==i ? 14 : 15),vc(0),infobg?vc(0):-1);
6923 ypos+=showfont_h+1;
6924 }
6925 }
6926 }
6927 clear_clip_rect(screen);
6928 if(prv_mode)
6929 do_previewtext();
6930 }
6931 // Show Errors & Details
6932 //This includes the presence of: Screen State Carryover, Timed Warp, Maze Path, the 'Sideview Gravity', 'Invisible Hero',
6933 //'Save Screen', 'Continue Here' and 'Treat As..' Screen Flags,
6934 // the String, every Room Type and Catch All, and all four Tile and Side Warps.
6935 if(!prv_mode && ShowInfo)
6936 {
6937 int32_t i=0;
6938 char buf[2048];
6939
6940 // Start with general information
6941 if(Map.CurrScr()->flags3&fINVISHERO)
6942 {
6943 sprintf(buf,"Invisible Hero");
6944 show_screen_error(buf,i++,vc(15));
6945 }
6946
6947 if(Map.getLayerTargetMap() > 0)
6948 {
6949 Map.setlayertarget(); //Now the text does not carry over when changing maps, but shifting back, it does not **re-appear** until you change screens.
6950 //It was also required to set some updates in onDecMap and onIncMap. #
6951 //This fixes Screen Info not displaying properly when changing maps. -Z
6952 //Needed to refresh the screen info. -Z ( 26th March, 2019 )
6953 int32_t m = Map.getLayerTargetMultiple();
6954 sprintf(buf,"Used as a layer by screen %d:%02X",Map.getLayerTargetMap(),Map.getLayerTargetScr());
6955 char buf2[24];
6956
6957 if(m>0)
6958 {
6959 sprintf(buf2," and %d other%s",m,m>1?"s":"");
6960 strcat(buf,buf2);
6961 }
6962
6963 show_screen_error(buf,i++,vc(15));
6964 }
6965
6966 if(Map.CurrScr()->nextmap)
6967 {
6968 sprintf(buf,"Screen State carries over to %d:%02X",Map.CurrScr()->nextmap,Map.CurrScr()->nextscr);
6969 show_screen_error(buf,i++,vc(15));
6970 }
6971
6972 if(Map.CurrScr()->timedwarptics)
6973 {
6974 sprintf(buf,"%s%sTimed Warp: %s",(Map.CurrScr()->flags4&fTIMEDDIRECT)?"Direct ":"",(Map.CurrScr()->flags5&fRANDOMTIMEDWARP)?"Random ":"",ticksstr(Map.CurrScr()->timedwarptics));
6975 show_screen_error(buf,i++,vc(15));
6976 }
6977
6978 if(Map.CurrScr()->flags&fMAZE)
6979 {
6980 sprintf(buf,"Maze Path: %s (Exit %s)",pathstr(Map.CurrScr()->path),mazedirstr[Map.CurrScr()->exitdir]);
6981 show_screen_error(buf,i++,vc(15));
6982 }
6983
6984 bool continuescreen = false, savecombo = false;
6985
6986 if(Map.CurrScr()->flags4&fAUTOSAVE)
6987 {
6988 sprintf(buf,"Automatic Save%s Screen", (Map.CurrScr()->flags6&fCONTINUEHERE) ? "-Continue":"");
6989 show_screen_error(buf,i++,vc(15));
6990 continuescreen = ((Map.CurrScr()->flags6&fCONTINUEHERE)!=0);
6991 savecombo = true;
6992 }
6993 else if(Map.CurrScr()->flags6&fCONTINUEHERE)
6994 {
6995 sprintf(buf,"Continue Screen");
6996 show_screen_error(buf,i++,vc(15));
6997 continuescreen = true;
6998 }
6999
7000 if(isSideViewGravity())
7001 {
7002 sprintf(buf,"Sideview Gravity");
7003 show_screen_error(buf,i++,vc(15));
7004 }
7005
7006 if(Map.CurrScr()->flags6 & (fCAVEROOM|fDUNGEONROOM))
7007 {
7008 sprintf(buf,"Treat As %s%s Screen", (Map.CurrScr()->flags6&fCAVEROOM) ? "Interior":"NES Dungeon",
7009 (Map.CurrScr()->flags6 & (fCAVEROOM|fDUNGEONROOM)) == (fCAVEROOM|fDUNGEONROOM) ? " or NES Dungeon":"");
7010 show_screen_error(buf,i++,vc(15));
7011 }
7012
7013 if(Map.CurrScr()->oceansfx != 0)
7014 {
7015 sprintf(buf,"Ambient Sound: %s",sfx_string[Map.CurrScr()->oceansfx]);
7016 show_screen_error(buf,i++,vc(15));
7017 }
7018
7019 if(Map.CurrScr()->bosssfx != 0)
7020 {
7021 sprintf(buf,"Boss Roar Sound: %s",sfx_string[Map.CurrScr()->bosssfx]);
7022 show_screen_error(buf,i++,vc(15));
7023 }
7024
7025 if(Map.CurrScr()->str)
7026 {
7027 strncpy(buf,MsgString(Map.CurrScr()->str, true, false),72);
7028 buf[72] = '\0';
7029 char shortbuf[72];
7030 strip_extra_spaces(buf);
7031 shorten_string(shortbuf, buf, get_zc_font(font_lfont_l), 72, 280);
7032 sprintf(buf,"String %s",shortbuf);
7033 show_screen_error(buf,i++,vc(15));
7034 }
7035
7036 if((Map.CurrScr()->flags&fWHISTLE) || (Map.CurrScr()->flags7&fWHISTLEWATER))
7037 {
7038 sprintf(buf,"Whistle ->%s%s%s",(Map.CurrScr()->flags&fWHISTLE)?" Stairs":"",
7039 (Map.CurrScr()->flags&fWHISTLE && Map.CurrScr()->flags7&fWHISTLEWATER)?", ":"",
7040 (Map.CurrScr()->flags7&fWHISTLEWATER)?"Dry Lake":"");
7041 show_screen_error(buf,i++,vc(15));
7042 }
7043
7044 switch(Map.CurrScr()->room)
7045 {
7046 case rSP_ITEM:
7047 sprintf(buf,"Special Item is %s",item_string[Map.CurrScr()->catchall]);
7048 show_screen_error(buf,i++, vc(15));
7049 break;
7050
7051 case rINFO:
7052 {
7053 int32_t shop = Map.CurrScr()->catchall;
7054 sprintf(buf,"Pay For Info: -%d, -%d, -%d",
7055 QMisc.info[shop].price[0],QMisc.info[shop].price[1],QMisc.info[shop].price[2]);
7056 show_screen_error(buf,i++, vc(15));
7057 }
7058 break;
7059
7060 case rMONEY:
7061 sprintf(buf,"Secret Money: %d Rupees",Map.CurrScr()->catchall);
7062 show_screen_error(buf,i++, vc(15));
7063 break;
7064
7065 case rGAMBLE:
7066 show_screen_error("Gamble Room",i++, vc(15));
7067 break;
7068
7069 case rREPAIR:
7070 sprintf(buf,"Door Repair: -%d Rupees",Map.CurrScr()->catchall);
7071 show_screen_error(buf,i++, vc(15));
7072 break;
7073
7074 case rRP_HC:
7075 sprintf(buf,"Take %s or %s", item_string[iRPotion], item_string[iHeartC]);
7076 show_screen_error(buf,i++, vc(15));
7077 break;
7078
7079 case rGRUMBLE:
7080 show_screen_error("Feed the Goriya",i++, vc(15));
7081 break;
7082
7083 case rTRIFORCE:
7084 show_screen_error("Triforce Check",i++, vc(15));
7085 break;
7086
7087 case rP_SHOP:
7088 case rSHOP:
7089 {
7090 int32_t shop = Map.CurrScr()->catchall;
7091 sprintf(buf,"%sShop: ",
7092 Map.CurrScr()->room==rP_SHOP ? "Potion ":"");
7093
7094 for(int32_t j=0; j<3; j++) if(QMisc.shop[shop].item[j]>0) // Print the 3 items and prices
7095 {
7096 strcat(buf,item_string[QMisc.shop[shop].item[j]]);
7097 strcat(buf,":");
7098 char pricebuf[8];
7099 sprintf(pricebuf,"%d",QMisc.shop[shop].price[j]);
7100 strcat(buf,pricebuf);
7101
7102 if(j<2 && QMisc.shop[shop].item[j+1]>0) strcat(buf,", ");
7103 }
7104
7105 show_screen_error(buf,i++, vc(15));
7106 }
7107 break;
7108
7109 case rBOTTLESHOP:
7110 {
7111 int32_t shop = Map.CurrScr()->catchall;
7112 sprintf(buf,"Bottle Shop: ");
7113
7114 for(int32_t j=0; j<3; j++) if(QMisc.bottle_shop_types[shop].fill[j]>0) // Print the 3 fills and prices
7115 {
7116 strcat(buf,QMisc.bottle_types[QMisc.bottle_shop_types[shop].fill[j]-1].name);
7117 strcat(buf,":");
7118 char pricebuf[8];
7119 sprintf(pricebuf,"%d",QMisc.bottle_shop_types[shop].price[j]);
7120 strcat(buf,pricebuf);
7121
7122 if(j<2 && QMisc.bottle_shop_types[shop].fill[j+1]>0) strcat(buf,", ");
7123 }
7124
7125 show_screen_error(buf,i++, vc(15));
7126 }
7127 break;
7128
7129 case rTAKEONE:
7130 {
7131 int32_t shop = Map.CurrScr()->catchall;
7132 sprintf(buf,"Take Only One: %s%s%s%s%s",
7133 QMisc.shop[shop].item[0]<1?"":item_string[QMisc.shop[shop].item[0]],QMisc.shop[shop].item[0]>0?", ":"",
7134 QMisc.shop[shop].item[1]<1?"":item_string[QMisc.shop[shop].item[1]],(QMisc.shop[shop].item[1]>0&&QMisc.shop[shop].item[2]>0)?", ":"",
7135 QMisc.shop[shop].item[2]<1?"":item_string[QMisc.shop[shop].item[2]]);
7136 show_screen_error(buf,i++, vc(15));
7137 }
7138 break;
7139
7140 case rBOMBS:
7141 sprintf(buf,"More Bombs: -%d Rupees",Map.CurrScr()->catchall);
7142 show_screen_error(buf,i++, vc(15));
7143 break;
7144
7145 case rARROWS:
7146 sprintf(buf,"More Arrows: -%d Rupees",Map.CurrScr()->catchall);
7147 show_screen_error(buf,i++, vc(15));
7148 break;
7149
7150 case rSWINDLE:
7151 sprintf(buf,"Leave Life or %d Rupees",Map.CurrScr()->catchall);
7152 show_screen_error(buf,i++, vc(15));
7153 break;
7154
7155 case r10RUPIES:
7156 show_screen_error("10 Rupees",i++, vc(15));
7157 break;
7158
7159 case rGANON:
7160 show_screen_error("Ganon Room",i++, vc(15));
7161 break;
7162
7163 case rZELDA:
7164 show_screen_error("Zelda Room",i++, vc(15));
7165 break;
7166
7167 case rMUPGRADE:
7168 show_screen_error("1/2 Magic Upgrade",i++, vc(15));
7169 break;
7170
7171 case rLEARNSLASH:
7172 show_screen_error("Learn Slash",i++, vc(15));
7173 break;
7174
7175 case rWARP:
7176 sprintf(buf,"3-Stair Warp: Warp Ring %d",Map.CurrScr()->catchall);
7177 show_screen_error(buf,i++, vc(15));
7178 break;
7179 }
7180
7181 bool undercombo = false, warpa = false, warpb = false, warpc = false, warpd = false, warpr = false;
7182
7183 word num_ffcs = Map.CurrScr()->numFFC();
7184 for(int32_t c=0; c<176+128+1+num_ffcs; ++c)
7185 {
7186 // Checks both combos, secret combos, undercombos and FFCs
7187 //Fixme:
7188 int32_t ctype =
7189 combobuf[vbound(
7190 (c>=305 ? Map.CurrScr()->ffcs[c-305].data :
7191 c>=304 ? Map.CurrScr()->undercombo :
7192 c>=176 ? Map.CurrScr()->secretcombo[c-176] :
7193 !Map.CurrScr()->valid ? 0 : // Sanity check: does room combo data exist?
7194 Map.CurrScr()->data[c]
7195 ), 0, MAXCOMBOS-1)].type;
7196
7197 if(!undercombo && integrityBoolUnderCombo(Map.CurrScr(),ctype))
7198 {
7199 undercombo = true;
7200 show_screen_error("Under Combo is combo 0",i++, vc(7));
7201 }
7202
7203 // Tile Warp types
7204 switch(ctype)
7205 {
7206 case cSAVE:
7207 case cSAVE2:
7208 if(!savecombo)
7209 {
7210 savecombo = true;
7211
7212 if(integrityBoolSaveCombo(Map.CurrScr(),ctype))
7213 show_screen_error("Save Screen",i++, vc(15));
7214 else
7215 show_screen_error("Save-Continue Screen",i++, vc(15));
7216 }
7217
7218 break;
7219
7220 case cSTAIRR:
7221 case cPITR:
7222 case cSWARPR:
7223 if(!warpr && (Map.CurrScr()->tilewarptype[0]==wtCAVE || Map.CurrScr()->tilewarptype[1]==wtCAVE ||
7224 Map.CurrScr()->tilewarptype[2]==wtCAVE || Map.CurrScr()->tilewarptype[3]==wtCAVE))
7225 {
7226 warpr = true;
7227 show_screen_error("Random Tile Warp contains Cave/Item Cellar",i++, vc(7));
7228 }
7229
7230 break;
7231
7232 case cCAVED:
7233 case cPITD:
7234 case cSTAIRD:
7235 case cCAVE2D:
7236 case cSWIMWARPD:
7237 case cDIVEWARPD:
7238 case cSWARPD:
7239 if(!warpd)
7240 {
7241 warpd = true;
7242 tile_warp_notification(3,buf);
7243 show_screen_error(buf,i++, vc(15));
7244 }
7245
7246 break;
7247
7248 case cCAVEC:
7249 case cPITC:
7250 case cSTAIRC:
7251 case cCAVE2C:
7252 case cSWIMWARPC:
7253 case cDIVEWARPC:
7254 case cSWARPC:
7255 if(!warpc)
7256 {
7257 warpc = true;
7258 tile_warp_notification(2,buf);
7259 show_screen_error(buf,i++, vc(15));
7260 }
7261
7262 break;
7263
7264 case cCAVEB:
7265 case cPITB:
7266 case cSTAIRB:
7267 case cCAVE2B:
7268 case cSWIMWARPB:
7269 case cDIVEWARPB:
7270 case cSWARPB:
7271 if(!warpb)
7272 {
7273 warpb = true;
7274 tile_warp_notification(1,buf);
7275 show_screen_error(buf,i++, vc(15));
7276 }
7277
7278 break;
7279
7280 case cCAVE:
7281 case cPIT:
7282 case cSTAIR:
7283 case cCAVE2:
7284 case cSWIMWARP:
7285 case cDIVEWARP:
7286 case cSWARPA:
7287 if(!warpa)
7288 {
7289 warpa = true;
7290 tile_warp_notification(0,buf);
7291 show_screen_error(buf,i++, vc(15));
7292 }
7293
7294 break;
7295 }
7296 }
7297
7298 int32_t sidewarpnotify = 0;
7299
7300 if(Map.CurrScr()->flags2&wfUP)
7301 {
7302 side_warp_notification(Map.CurrScr()->sidewarpindex&3,0,buf);
7303 show_screen_error(buf,i++, vc(15));
7304 sidewarpnotify|=(1<<(Map.CurrScr()->sidewarpindex&3));
7305 }
7306
7307 if(Map.CurrScr()->flags2&wfDOWN)
7308 {
7309 side_warp_notification((Map.CurrScr()->sidewarpindex>>2)&3,1,buf);
7310 show_screen_error(buf,i++, vc(15));
7311 sidewarpnotify|=(1<<((Map.CurrScr()->sidewarpindex>>2)&3));
7312 }
7313
7314 if(Map.CurrScr()->flags2&wfLEFT)
7315 {
7316 side_warp_notification((Map.CurrScr()->sidewarpindex>>4)&3,2,buf);
7317 show_screen_error(buf,i++, vc(15));
7318 sidewarpnotify|=(1<<((Map.CurrScr()->sidewarpindex>>4)&3));
7319 }
7320
7321 if(Map.CurrScr()->flags2&wfRIGHT)
7322 {
7323 side_warp_notification((Map.CurrScr()->sidewarpindex>>6)&3,3,buf);
7324 show_screen_error(buf,i++, vc(15));
7325 sidewarpnotify|=(1<<((Map.CurrScr()->sidewarpindex>>6)&3));
7326 }
7327
7328 if(!(sidewarpnotify&1) && Map.CurrScr()->timedwarptics)
7329 {
7330 side_warp_notification(0,4,buf); // Timed Warp
7331 show_screen_error(buf,i++, vc(15));
7332 }
7333
7334 // Now for errors
7335 if((Map.CurrScr()->flags4&fSAVEROOM) && !savecombo) show_screen_error("Save Point->Continue Here, but no Save Point combo?",i++, vc(14));
7336
7337 if(integrityBoolEnemiesItem(Map.CurrScr())) show_screen_error("Enemies->Item, but no enemies",i++, vc(7));
7338
7339 if(integrityBoolEnemiesSecret(Map.CurrScr())) show_screen_error("Enemies->Secret, but no enemies",i++, vc(7));
7340
7341 if(integrityBoolGuyNoString(Map.CurrScr())) show_screen_error("Non-Fairy Guy, but String is (none)",i++, vc(14));
7342
7343 if(integrityBoolRoomNoGuy(Map.CurrScr())) show_screen_error("Guy is (none)",i++, vc(14));
7344
7345 if(integrityBoolRoomNoString(Map.CurrScr())) show_screen_error("String is (none)",i++, vc(14));
7346
7347 if(integrityBoolRoomNoGuyNoString(Map.CurrScr())) show_screen_error("Guy and String are (none)",i++, vc(14));
7348 }
7349
7350 if(zoom_delay)
7351 draw_screenunit(rSCRMAP,flags);
7352
7353 if(earlyret)
7354 return;
7355
7356 //Draw the Main Menu
7357 rectfill(screen,mainbar.x,mainbar.y,mainbar.x+mainbar.w-1,mainbar.y+mainbar.h-1,jwin_pal[jcBOX]);
7358 jwin_draw_frame(screen,mainbar.x,mainbar.y,mainbar.w,mainbar.h,FR_WIN);
7359
7360 FONT* oldfont = font;
7361 font = get_custom_font(CFONT_GUI);
7362
7363 //Drawmode button
7364 draw_text_button(screen,drawmode_btn.x,drawmode_btn.y,drawmode_btn.w,drawmode_btn.h,dm_names[draw_mode],vc(1),vc(14),0,true);
7365 //Compact button
7366 draw_text_button(screen,compactbtn.x, compactbtn.y, compactbtn.w, compactbtn.h, is_compact ? "< Expand" : "> Compact", vc(1),vc(14),0,true);
7367 //Zoom buttons
7368 zoom_in_btn_disabled = num_screens_to_draw == 1;
7369 zoom_out_btn_disabled = num_screens_to_draw == mapscreen_num_screens_to_draw_max;
7370 draw_text_button(screen,zoominbtn.x, zoominbtn.y, zoominbtn.w, zoominbtn.h, "+", vc(1),vc(14),zoom_in_btn_disabled ? D_DISABLED : 0,true);
7371 draw_text_button(screen,zoomoutbtn.x, zoomoutbtn.y, zoomoutbtn.w, zoomoutbtn.h, "-", vc(1),vc(14),zoom_out_btn_disabled ? D_DISABLED : 0,true);
7372
7373 font = oldfont;
7374
7375 d_nbmenu_proc(MSG_DRAW, &dialogs[0], 0);
7376
7377 ComboBrushPause=0;
7378
7379 if(update)
7380 custom_vsync();
7381 is_refreshing = refreshing = false;
7382 11 }
7383
7384 12 static int minimap_tooltip_id = ttip_register_id();
7385
7386 void select_scr()
7387 {
7388 if(Map.getCurrMap()>=Map.getMapCount())
7389 return;
7390
7391 int32_t tempcb=ComboBrush;
7392 ComboBrush=0;
7393
7394 size_and_pos const& real_mini = zoomed_minimap ? real_minimap_zoomed : real_minimap;
7395
7396 auto prev_cursor = Map.getCursor();
7397 Map.ConfigureCursorHistory(false);
7398
7399 //scooby
7400 while(gui_mouse_b())
7401 {
7402 int32_t x=gui_mouse_x();
7403 int32_t y=gui_mouse_y();
7404
7405 int32_t ind = real_mini.rectind(x,y);
7406
7407 if(ind>=MAPSCRS)
7408 ind-=16;
7409
7410 if(ind > -1 && ind != Map.getCurrScr())
7411 {
7412 Map.setCurrScr(ind);
7413 }
7414
7415 custom_vsync();
7416 refresh(rALL);
7417 }
7418
7419 ComboBrush=tempcb;
7420
7421 Map.ConfigureCursorHistory(true);
7422 if (prev_cursor != Map.getCursor())
7423 Map.pushCursorToHistory(prev_cursor);
7424 }
7425
7426 bool select_favorite()
7427 {
7428 int32_t tempcb=ComboBrush;
7429 ComboBrush=0;
7430 bool valid=false;
7431
7432 while(gui_mouse_b())
7433 {
7434 valid=false;
7435 int32_t x=gui_mouse_x();
7436
7437 if(x<favorites_list.x)
7438 x=favorites_list.x;
7439
7440 if(x>favorites_list.x+(favorites_list.w*favorites_list.xscale)-1)
7441 x=favorites_list.x+(favorites_list.w*favorites_list.xscale)-1;
7442
7443 int32_t y=gui_mouse_y();
7444
7445 if(y<favorites_list.y)
7446 y=favorites_list.y;
7447
7448 if(y>favorites_list.y+(favorites_list.h*favorites_list.yscale)-1)
7449 y=favorites_list.y+(favorites_list.h*favorites_list.yscale)-1;
7450
7451 int32_t tempc=(((y-favorites_list.y)/favorites_list.yscale)*FAVORITECOMBO_PER_ROW)+((x-favorites_list.x)/favorites_list.xscale) + FAVORITECOMBO_PER_PAGE * FavoriteComboPage;
7452
7453 if(tempc >= MAXFAVORITECOMBOS)
7454 {
7455 //Nothing, invalid
7456 }
7457 else
7458 {
7459 if(favorite_combos[tempc]!=-1)
7460 {
7461 switch(favorite_combo_modes[tempc])
7462 {
7463 case dm_alias:
7464 draw_mode = dm_alias;
7465 combo_apos = favorite_combos[tempc];
7466 break;
7467 case dm_cpool:
7468 draw_mode = dm_cpool;
7469 combo_pool_pos = favorite_combos[tempc];
7470 break;
7471 case dm_auto:
7472 draw_mode = dm_auto;
7473 combo_auto_pos = favorite_combos[tempc];
7474 break;
7475 default:
7476 draw_mode = dm_normal;
7477 Combo = favorite_combos[tempc];
7478 }
7479 if(AutoBrush)
7480 BrushWidth = BrushHeight = 1;
7481 valid=true;
7482 fix_drawing_mode_menu();
7483 }
7484 }
7485
7486 custom_vsync();
7487 refresh(rALL);
7488 }
7489
7490 ComboBrush=tempcb;
7491 return valid;
7492 }
7493
7494 void select_combo(int32_t clist)
7495 {
7496 current_combolist=clist;
7497 int32_t tempcb=ComboBrush;
7498 ComboBrush=0;
7499
7500 int autobrush_cx = -1, autobrush_cy = -1;
7501 int autobrush_first = First[current_combolist];
7502 auto& curlist = combolist[current_combolist];
7503 AutoBrushRevert = (key[KEY_ALT]||key[KEY_ALTGR]);
7504 while(gui_mouse_b())
7505 {
7506 int32_t x=gui_mouse_x();
7507
7508 if(x<curlist.x)
7509 x=curlist.x;
7510
7511 if(x>curlist.x+(curlist.w*curlist.xscale)-1)
7512 x=curlist.x+(curlist.w*curlist.xscale)-1;
7513
7514 int32_t y=gui_mouse_y();
7515
7516 if(y<curlist.y)
7517 y=curlist.y;
7518
7519 if(y>curlist.y+(curlist.h*curlist.yscale)-1)
7520 y=curlist.y+(curlist.h*curlist.yscale)-1;
7521
7522 int cx = ((x-curlist.x)/curlist.xscale), cy = ((y-curlist.y)/curlist.yscale);
7523 if(AutoBrush)
7524 {
7525 if(autobrush_cx < 0)
7526 {
7527 autobrush_cx = cx;
7528 autobrush_cy = cy;
7529 }
7530 BrushWidth = vbound(abs(autobrush_cx-cx)+1,1,16);
7531 BrushHeight = vbound(abs(autobrush_cy-cy)+1,1,11);
7532 cx = std::min(autobrush_cx,cx);
7533 cy = std::min(autobrush_cy,cy);
7534 }
7535 Combo=(cy*curlist.w)+cx+First[current_combolist];
7536 custom_vsync();
7537 refresh(rALL);
7538 if(AutoBrush) //Prevent any scrolling
7539 First[current_combolist] = autobrush_first;
7540 }
7541 if(key[KEY_ALT]||key[KEY_ALTGR])
7542 AutoBrushRevert = true;
7543 position_mouse_z(0);
7544 ComboBrush=tempcb;
7545 }
7546
7547 void select_comboa(int32_t clist)
7548 {
7549 current_comboalist=clist;
7550 int32_t tempcb=ComboBrush;
7551 ComboBrush=0;
7552 alias_cset_mod=0;
7553
7554 auto& curlist = comboaliaslist[current_comboalist];
7555 while(gui_mouse_b())
7556 {
7557 int32_t x=gui_mouse_x();
7558
7559 if(x<curlist.x)
7560 x=curlist.x;
7561
7562 if(x>curlist.x+(curlist.w*curlist.xscale)-1)
7563 x=curlist.x+(curlist.w*curlist.xscale)-1;
7564
7565 int32_t y=gui_mouse_y();
7566
7567 if(y<curlist.y)
7568 y=curlist.y;
7569
7570 if(y>curlist.y+(curlist.h*curlist.yscale)-1)
7571 y=curlist.y+(curlist.h*curlist.yscale)-1;
7572
7573 combo_apos=(((y-curlist.y)/curlist.yscale)*curlist.w)+((x-curlist.x)/curlist.xscale)+combo_alistpos[current_comboalist];
7574 custom_vsync();
7575 refresh(rALL);
7576 }
7577
7578 ComboBrush=tempcb;
7579 }
7580
7581 void select_combop(int32_t clist)
7582 {
7583 current_cpoollist=clist;
7584 int32_t tempcb=ComboBrush;
7585 ComboBrush=0;
7586
7587 auto& curlist = comboaliaslist[current_cpoollist];
7588 while(gui_mouse_b())
7589 {
7590 int32_t x=gui_mouse_x();
7591
7592 if(x<curlist.x) x=curlist.x;
7593
7594 if(x>curlist.x+(curlist.w*curlist.xscale)-1)
7595 x=curlist.x+(curlist.w*curlist.xscale)-1;
7596
7597 int32_t y=gui_mouse_y();
7598
7599 if(y<curlist.y) y=curlist.y;
7600
7601 if(y>curlist.y+(curlist.h*curlist.yscale)-1)
7602 y=curlist.y+(curlist.h*curlist.yscale)-1;
7603
7604 combo_pool_pos=(((y-curlist.y)/curlist.yscale)*curlist.w)+((x-curlist.x)/curlist.xscale)+combo_pool_listpos[current_cpoollist];
7605 custom_vsync();
7606 refresh(rALL);
7607 }
7608
7609 ComboBrush=tempcb;
7610 }
7611
7612 void select_autocombo(int32_t clist)
7613 {
7614 current_cautolist = clist;
7615 int32_t tempcb = ComboBrush;
7616 ComboBrush = 0;
7617
7618 auto& curlist = comboaliaslist[current_cautolist];
7619 while (gui_mouse_b())
7620 {
7621 int32_t x = gui_mouse_x();
7622
7623 if (x < curlist.x) x = curlist.x;
7624
7625 if (x > curlist.x + (curlist.w * curlist.xscale) - 1)
7626 x = curlist.x + (curlist.w * curlist.xscale) - 1;
7627
7628 int32_t y = gui_mouse_y();
7629
7630 if (y < curlist.y) y = curlist.y;
7631
7632 if (y > curlist.y + (curlist.h * curlist.yscale) - 1)
7633 y = curlist.y + (curlist.h * curlist.yscale) - 1;
7634
7635 combo_auto_pos = (((y - curlist.y) / curlist.yscale) * curlist.w) + ((x - curlist.x) / curlist.xscale) + combo_auto_listpos[current_cautolist];
7636 cauto_height = combo_autos[combo_auto_pos].getArg() + 1;
7637 custom_vsync();
7638 refresh(rALL);
7639 }
7640
7641 ComboBrush = tempcb;
7642 }
7643
7644 void update_combobrush()
7645 {
7646 clear_bitmap(brushbmp);
7647
7648 if(draw_mode==dm_alias)
7649 {
7650 //int32_t count=(combo_aliases[combo_apos].width+1)*(combo_aliases[combo_apos].height+1)*(comboa_lmasktotal(combo_aliases[combo_apos].layermask));
7651 for(int32_t z=0; z<=comboa_lmasktotal(combo_aliases[combo_apos].layermask); z++)
7652 {
7653 for(int32_t y=0; y<=combo_aliases[combo_apos].height; y++)
7654 {
7655 for(int32_t x=0; x<=combo_aliases[combo_apos].width; x++)
7656 {
7657 int32_t position = ((y*(combo_aliases[combo_apos].width+1))+x)+((combo_aliases[combo_apos].width+1)*(combo_aliases[combo_apos].height+1)*z);
7658
7659 if(combo_aliases[combo_apos].combos[position])
7660 {
7661 if(z==0)
7662 {
7663 putcombo(brushbmp,x<<4,y<<4,combo_aliases[combo_apos].combos[position],wrap(combo_aliases[combo_apos].csets[position]+alias_cset_mod, 0, 13));
7664 }
7665 else
7666 {
7667 overcombo(brushbmp,x<<4,y<<4,combo_aliases[combo_apos].combos[position],wrap(combo_aliases[combo_apos].csets[position]+alias_cset_mod, 0, 13));
7668 }
7669 }
7670 }
7671 }
7672 }
7673
7674 int xoff = 6, yoff = 6;
7675 if(FloatBrush) // Offset the floating pixels, so the 'x' appears centered on the combo still -Em
7676 {
7677 xoff += 2;
7678 yoff += 2;
7679 }
7680 if(alias_origin & 1) // Right-align
7681 xoff += combo_aliases[combo_apos].width*16;
7682 if(alias_origin & 2) // Bottom-align
7683 yoff += combo_aliases[combo_apos].height*16;
7684
7685 textprintf_shadowed_ex(brushbmp, get_zc_font(font_sfont), xoff, yoff, vc(15), vc(0), -1, "x");
7686 }
7687 else if(draw_mode != dm_cpool)
7688 {
7689 int32_t cid = combobrushoverride > -1 ? combobrushoverride : Combo;
7690 int32_t c = 0;
7691
7692 for(int32_t i=0; i<256; i++)
7693 {
7694 if(unsigned(cid+c) >= MAXCOMBOS) break;
7695 if(((i%COMBOS_PER_ROW)<BrushWidth)&&((i/COMBOS_PER_ROW)<BrushHeight))
7696 {
7697 put_combo(brushbmp,(i%COMBOS_PER_ROW)<<4,(i/COMBOS_PER_ROW)<<4,cid+c,CSet,Flags&(cFLAGS|cWALK),0);
7698 }
7699
7700 if(((cid+c)&3)==3)
7701 c+=48;
7702
7703 ++c;
7704
7705 if((i%COMBOS_PER_ROW)==(COMBOS_PER_ROW-1))
7706 c-=256;
7707 }
7708 }
7709 }
7710
7711 byte relational_source_grid[256]=
7712 {
7713 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7714 16, 16, 17, 17, 18, 18, 19, 19, 16, 16, 17, 17, 18, 18, 19, 19,
7715 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
7716 24, 24, 24, 24, 25, 25, 25, 25, 24, 24, 24, 24, 25, 25, 25, 25,
7717 26, 27, 26, 27, 26, 27, 26, 27, 28, 29, 28, 29, 28, 29, 28, 29,
7718 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
7719 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
7720 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
7721 34, 35, 36, 37, 34, 35, 36, 37, 34, 35, 36, 37, 34, 35, 36, 37,
7722 38, 38, 39, 39, 38, 38, 39, 39, 38, 38, 39, 39, 38, 38, 39, 39,
7723 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
7724 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
7725 42, 43, 42, 43, 42, 43, 42, 43, 42, 43, 42, 43, 42, 43, 42, 43,
7726 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
7727 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
7728 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46
7729 };
7730
7731 static void draw_autocombo(ComboPosition combo_pos, bool rclick, bool pressframe = false)
7732 {
7733 combo_auto &ca = combo_autos[combo_auto_pos];
7734 int screen = Map.getScreenForPosition(combo_pos);
7735 int pos = combo_pos.truncate();
7736
7737 if (ca.valid())
7738 {
7739 switch (ca.getType())
7740 {
7741 case AUTOCOMBO_BASIC:
7742 {
7743 AutoPattern::autopattern_basic ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7744 if (rclick)
7745 ap.erase(screen, pos);
7746 else
7747 ap.execute(screen, pos);
7748 break;
7749 }
7750 case AUTOCOMBO_Z1:
7751 {
7752 AutoPattern::autopattern_flatmtn ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7753 if (rclick)
7754 ap.erase(screen, pos);
7755 else
7756 ap.execute(screen, pos);
7757 break;
7758 }
7759 case AUTOCOMBO_FENCE:
7760 {
7761 AutoPattern::autopattern_fence ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7762 if (rclick)
7763 ap.erase(screen, pos);
7764 else
7765 ap.execute(screen, pos);
7766 break;
7767 }
7768 case AUTOCOMBO_Z4:
7769 {
7770 AutoPattern::autopattern_cakemtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7771 if (rclick)
7772 ap.erase(screen, pos);
7773 else
7774 ap.execute(screen, pos);
7775 break;
7776 }
7777 case AUTOCOMBO_RELATIONAL:
7778 {
7779 AutoPattern::autopattern_relational ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7780 if (rclick)
7781 ap.erase(screen, pos);
7782 else
7783 ap.execute(screen, pos);
7784 break;
7785 }
7786 case AUTOCOMBO_DGNCARVE:
7787 {
7788 AutoPattern::autopattern_dungeoncarve ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7789 if (rclick)
7790 ap.erase(screen, pos);
7791 else
7792 ap.execute(screen, pos);
7793 break;
7794 }
7795 case AUTOCOMBO_DOR:
7796 {
7797 AutoPattern::autopattern_dormtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7798 if (rclick)
7799 ap.erase(screen, pos);
7800 else
7801 ap.execute(screen, pos);
7802 break;
7803 }
7804 case AUTOCOMBO_TILING:
7805 {
7806 if (pressframe && (key[KEY_LSHIFT] || key[KEY_RSHIFT]))
7807 {
7808 int32_t x = (screen % 16) * 16 + (pos % 16);
7809 int32_t y = (screen / 16) * 11 + (pos / 16);
7810 byte w = (ca.getArg() & 0xF) + 1;
7811 byte h = ((ca.getArg() >> 4) & 0xF) + 1;
7812 ca.setOffsets(x % w, y % h);
7813 }
7814 AutoPattern::autopattern_tiling ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7815 if (rclick)
7816 ap.erase(screen, pos);
7817 else
7818 ap.execute(screen, pos);
7819 break;
7820 }
7821 case AUTOCOMBO_REPLACE:
7822 {
7823 AutoPattern::autopattern_replace ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7824 if (rclick)
7825 ap.erase(screen, pos);
7826 else
7827 ap.execute(screen, pos);
7828 break;
7829 }
7830 case AUTOCOMBO_DENSEFOREST:
7831 {
7832 if (pressframe && (key[KEY_LSHIFT] || key[KEY_RSHIFT]))
7833 {
7834 int32_t x = (screen % 16) * 16 + (pos % 16);
7835 int32_t y = (screen / 16) * 11 + (pos / 16);
7836 ca.setOffsets(x % 2, y % 2);
7837 }
7838 AutoPattern::autopattern_denseforest ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7839 if (rclick)
7840 ap.erase(screen, pos);
7841 else
7842 ap.execute(screen, pos);
7843 break;
7844 }
7845 case AUTOCOMBO_EXTEND:
7846 {
7847 if (CHECK_CTRL_CMD)
7848 break;
7849 AutoPattern::autopattern_extend ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7850 if (rclick)
7851 ap.erase(screen, pos);
7852 else
7853 ap.execute(screen, pos);
7854 break;
7855 }
7856 }
7857 }
7858 else
7859 {
7860 ca.updateValid();
7861 if(!ca.valid())
7862 InfoDialog("Notice", "The autocombo you're trying to use is invalid. Reason:"
7863 + ca.getInvalidReason()).show();
7864 }
7865 }
7866
7867 static void draw_autocombo_command(ComboPosition combo_pos, int32_t cmd = 0, int32_t arg = 0)
7868 {
7869 combo_auto ca = combo_autos[combo_auto_pos];
7870 int screen = Map.getScreenForPosition(combo_pos);
7871 int pos = combo_pos.truncate();
7872
7873 if (ca.valid())
7874 {
7875 switch (ca.getType())
7876 {
7877 case AUTOCOMBO_FENCE:
7878 {
7879 AutoPattern::autopattern_fence ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7880 ap.flip_all_connected(screen, pos, 2048);
7881 break;
7882 }
7883 case AUTOCOMBO_Z4:
7884 {
7885 AutoPattern::autopattern_cakemtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7886 switch (cmd)
7887 {
7888 case 0: // Flip
7889 ap.flip_all_connected(screen, pos, 2048);
7890 break;
7891 case 1: // Grow
7892 ap.resize_connected(screen, pos, 2048, vbound(arg, 1, 9));
7893 break;
7894 }
7895 }
7896 }
7897 }
7898 }
7899
7900 static int32_t get_autocombo_floating_cid(ComboPosition combo_pos, bool clicked)
7901 {
7902 combo_auto& ca = combo_autos[combo_auto_pos];
7903 int screen = Map.getScreenForPosition(combo_pos);
7904 int pos = combo_pos.truncate();
7905 int cid = 0;
7906
7907 if (ca.valid() && Map.isValidPosition(mouse_combo_pos))
7908 {
7909 switch (ca.getType())
7910 {
7911 case AUTOCOMBO_BASIC:
7912 {
7913 AutoPattern::autopattern_basic ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7914 cid = ap.get_floating_cid(screen, pos);
7915 break;
7916 }
7917
7918 case AUTOCOMBO_Z1:
7919 {
7920 AutoPattern::autopattern_flatmtn ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7921 cid = ap.get_floating_cid(screen, pos);
7922 break;
7923 }
7924 case AUTOCOMBO_FENCE:
7925 {
7926 AutoPattern::autopattern_fence ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7927 cid = ap.get_floating_cid(screen, pos);
7928 break;
7929 }
7930 case AUTOCOMBO_Z4:
7931 {
7932 AutoPattern::autopattern_cakemtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7933 cid = ap.get_floating_cid(screen, pos);
7934 break;
7935 }
7936 case AUTOCOMBO_RELATIONAL:
7937 {
7938 AutoPattern::autopattern_relational ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7939 cid = ap.get_floating_cid(screen, pos);
7940 break;
7941 }
7942 case AUTOCOMBO_DGNCARVE:
7943 {
7944 AutoPattern::autopattern_dungeoncarve ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7945 cid = ap.get_floating_cid(screen, pos);
7946 break;
7947 }
7948 case AUTOCOMBO_DOR:
7949 {
7950 AutoPattern::autopattern_dormtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7951 cid = ap.get_floating_cid(screen, pos);
7952 break;
7953 }
7954 case AUTOCOMBO_TILING:
7955 {
7956 std::pair<byte, byte> offs = ca.getOffsets();
7957 if (!clicked && (key[KEY_LSHIFT] || key[KEY_RSHIFT]))
7958 {
7959 int32_t x = (screen % 16) * 16 + (pos % 16);
7960 int32_t y = (screen / 16) * 11 + (pos / 16);
7961 byte w = (ca.getArg() & 0xF) + 1;
7962 byte h = ((ca.getArg() >> 4) & 0xF) + 1;
7963 offs.first = (x % w);
7964 offs.second = (y % h);
7965 }
7966 AutoPattern::autopattern_tiling ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7967 cid = ap.get_floating_cid(screen, pos);
7968 break;
7969 }
7970 case AUTOCOMBO_REPLACE:
7971 {
7972 AutoPattern::autopattern_replace ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7973 cid = ap.get_floating_cid(screen, pos);
7974 break;
7975 }
7976 case AUTOCOMBO_DENSEFOREST:
7977 {
7978 AutoPattern::autopattern_denseforest ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7979 cid = ap.get_floating_cid(screen, pos);
7980 break;
7981 }
7982 case AUTOCOMBO_EXTEND:
7983 {
7984 AutoPattern::autopattern_extend ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7985 cid = ap.get_floating_cid(screen, pos);
7986 break;
7987 }
7988 }
7989 }
7990 return cid;
7991 }
7992
7993 void change_autocombo_height(int32_t change)
7994 {
7995 bool can_change = false;
7996 if (draw_mode == dm_auto)
7997 {
7998 combo_auto ca = combo_autos[combo_auto_pos];
7999 switch (ca.getType())
8000 {
8001 case AUTOCOMBO_Z4:
8002 can_change = true;
8003 [[fallthrough]];
8004 case AUTOCOMBO_DOR:
8005 break;
8006 default:
8007 return;
8008 }
8009 }
8010 else
8011 return;
8012
8013 int32_t x = gui_mouse_x();
8014 int32_t y = gui_mouse_y();
8015 double startx = mapscreen_x + (showedges ? (16 * mapscreen_single_scale) : 0);
8016 double starty = mapscreen_y + (showedges ? (16 * mapscreen_single_scale) : 0);
8017 int32_t startxint = mapscreen_x + (showedges ? int32_t(16 * mapscreen_single_scale) : 0);
8018 int32_t startyint = mapscreen_y + (showedges ? int32_t(16 * mapscreen_single_scale) : 0);
8019 ComboPosition pos = get_mapscreen_mouse_combo_pos();
8020
8021 if (can_change && isinRect(x, y, startxint, startyint, int32_t(startx + (256 * mapscreen_single_scale) - 1), int32_t(starty + (176 * mapscreen_single_scale) - 1)))
8022 {
8023 Map.StartListCommand();
8024 draw_autocombo_command(pos, 1, cauto_height + change);
8025 Map.FinishListCommand();
8026 }
8027 cauto_height = vbound(cauto_height + change, 1, 9);
8028 }
8029
8030 void draw(bool justcset)
8031 {
8032 combo_pool const& pool = combo_pools[combo_pool_pos];
8033 if(draw_mode == dm_cpool && !pool.valid())
8034 return;
8035 mark_save_dirty();
8036
8037 refresh(rMAP+rSCRMAP);
8038 ComboPosition last_pos = {-1, -1};
8039
8040 Map.StartListCommand();
8041 bool pressframe = true;
8042 while(gui_mouse_b())
8043 {
8044 int32_t x=gui_mouse_x();
8045 int32_t y=gui_mouse_y();
8046 double startx=mapscreen_x+(showedges?(16*mapscreen_single_scale):0);
8047 double starty=mapscreen_y+(showedges?(16*mapscreen_single_scale):0);
8048 int32_t startxint=mapscreen_x+(showedges?int32_t(16*mapscreen_single_scale):0);
8049 int32_t startyint=mapscreen_y+(showedges?int32_t(16*mapscreen_single_scale):0);
8050 int num_combos_width = 16 * Map.getViewSize();
8051 int num_combos_height = 11 * Map.getViewSize();
8052
8053 if(isinRect(x,y,startxint,startyint,int32_t(startx+(256*mapscreen_screenunit_scale)-1),int32_t(starty+(176*mapscreen_screenunit_scale)-1)))
8054 {
8055 int32_t cxstart=(x-startx)/(16*mapscreen_single_scale);
8056 int32_t cystart=(y-starty)/(16*mapscreen_single_scale);
8057 ComboPosition combo_start = {cxstart, cystart};
8058 if (pressframe)
8059 {
8060 last_pos = combo_start;
8061 }
8062 else if (combo_start == last_pos)
8063 {
8064 custom_vsync();
8065 refresh(rALL);
8066 continue;
8067 }
8068 else if(draw_mode == dm_auto)
8069 {
8070 // TODO: support when zoomed out.
8071 if (combo_autos[combo_auto_pos].getType() == AUTOCOMBO_FENCE || combo_autos[combo_auto_pos].getType() == AUTOCOMBO_Z4)
8072 {
8073 // Don't allow moving the brush at anything but cardinal directions while in these modes
8074 bool did_diag = std::abs(combo_start.x - last_pos.x) == 1 && std::abs(combo_start.y - last_pos.y) == 1;
8075
8076 if (did_diag)
8077 {
8078 int32_t oldx = last_pos.x;
8079 int32_t oldy = last_pos.y;
8080 int32_t cx = (oldx * 16 * mapscreen_single_scale) + 8;
8081 int32_t cy = (oldy * 16 * mapscreen_single_scale) + 8;
8082 int32_t nx = x - startxint;
8083 int32_t ny = y - startyint;
8084 if (std::abs(nx - cx) < std::abs(ny - cy))
8085 {
8086 oldy = vbound(oldy + ((ny - cy) < 0 ? -1 : 1), 0, 11);
8087 }
8088 else
8089 {
8090 oldx = vbound(oldx + ((nx - cx) < 0 ? -1 : 1), 0, 15);
8091 }
8092 combo_start = {oldx, oldy};
8093 }
8094 }
8095 }
8096 last_pos = combo_start;
8097
8098 switch(draw_mode)
8099 {
8100 case dm_normal:
8101 {
8102 int32_t cc=Combo;
8103
8104 for(int32_t cy=0; cy+cystart<num_combos_height&&cy<BrushHeight; cy++)
8105 {
8106 for(int32_t cx=0; cx+cxstart<num_combos_width&&cx<BrushWidth; cx++)
8107 {
8108 auto pos = combo_start + ComboPosition{cx, cy};
8109 cc=Combo + cx + cy*4;
8110 Map.DoSetComboCommand(pos, justcset ? -1 : cc, CSet);
8111 }
8112 }
8113
8114 update_combobrush();
8115 }
8116 break;
8117 case dm_cpool:
8118 {
8119 int32_t cid = Combo;
8120 int8_t cs = CSet;
8121 pool.pick(cid,cs);
8122 Map.DoSetComboCommand(combo_start, justcset ? -1 : cid, cs);
8123
8124 update_combobrush();
8125 }
8126 break;
8127
8128 case dm_alias:
8129 {
8130 combo_alias *combo = &combo_aliases[combo_apos];
8131 if(!combo->layermask)
8132 {
8133 int32_t ox=0, oy=0;
8134
8135 switch(alias_origin)
8136 {
8137 case 0:
8138 ox=0;
8139 oy=0;
8140 break;
8141
8142 case 1:
8143 ox=(combo->width);
8144 oy=0;
8145 break;
8146
8147 case 2:
8148 ox=0;
8149 oy=(combo->height);
8150 break;
8151
8152 case 3:
8153 ox=(combo->width);
8154 oy=(combo->height);
8155 break;
8156 }
8157
8158 for(int32_t cy=0; cy-oy+cystart<num_combos_height&&cy<=combo->height; cy++)
8159 {
8160 for(int32_t cx=0; cx-ox+cxstart<num_combos_width&&cx<=combo->width; cx++)
8161 {
8162 if((cx+cxstart-ox>=0)&&(cy+cystart-oy>=0))
8163 {
8164 int32_t p=(cy*(combo->width+1))+cx;
8165
8166 if(combo->combos[p])
8167 {
8168 auto pos = combo_start + ComboPosition{cx - ox, cy - oy};
8169 Map.DoSetComboCommand(pos, combo->combos[p], wrap(combo->csets[p]+alias_cset_mod, 0, 13));
8170 }
8171 }
8172 }
8173 }
8174 }
8175 else
8176 {
8177 int32_t laypos = 0;
8178 int32_t ox=0, oy=0;
8179
8180 switch(alias_origin)
8181 {
8182 case 0:
8183 ox=0;
8184 oy=0;
8185 break;
8186
8187 case 1:
8188 ox=(combo->width);
8189 oy=0;
8190 break;
8191
8192 case 2:
8193 ox=0;
8194 oy=(combo->height);
8195 break;
8196
8197 case 3:
8198 ox=(combo->width);
8199 oy=(combo->height);
8200 break;
8201 }
8202
8203 for(int32_t cz=0; cz<7; cz++)
8204 {
8205 if (cz > 0 && !(combo->layermask & (1<<(cz-1))))
8206 continue;
8207
8208 if (cz > 0)
8209 laypos++;
8210
8211 for(int32_t cy=0; cy-oy+cystart<num_combos_height&&cy<=combo->height; cy++)
8212 {
8213 for(int32_t cx=0; cx-ox+cxstart<num_combos_width&&cx<=combo->width; cx++)
8214 {
8215 if((cx+cxstart-ox>=0)&&(cy+cystart-oy>=0))
8216 {
8217 int32_t p=((cy*(combo->width+1))+cx)+((combo->width+1)*(combo->height+1)*laypos);
8218
8219 if (combo->combos[p])
8220 {
8221 auto pos = combo_start + ComboPosition{cx - ox, cy - oy};
8222 if(cz > 0 && Map.Scr(pos)->layermap[cz - 1] == 0)
8223 continue;
8224 int prev = CurrentLayer;
8225 CurrentLayer = cz;
8226 Map.DoSetComboCommand(pos, combo->combos[p], wrap(combo->csets[p]+alias_cset_mod, 0, 13));
8227 CurrentLayer = prev;
8228 }
8229 }
8230 }
8231 }
8232 }
8233 }
8234
8235 break;
8236 }
8237
8238 case dm_auto:
8239 {
8240 draw_autocombo(combo_start, gui_mouse_b() & 2, pressframe);
8241
8242 combobrushoverride = get_autocombo_floating_cid(combo_start, true);
8243 update_combobrush();
8244 }
8245 }
8246 }
8247 pressframe = false;
8248
8249 custom_vsync();
8250 refresh(rALL);
8251 }
8252
8253 Map.FinishListCommand();
8254 if(AutoBrushRevert)
8255 {
8256 AutoBrushRevert = false;
8257 BrushWidth = 1;
8258 BrushHeight = 1;
8259 }
8260 }
8261
8262 static void replace(ComboPosition start)
8263 {
8264 int32_t cid = Combo;
8265 int8_t cs = CSet;
8266 combo_pool const& pool = combo_pools[combo_pool_pos];
8267 if(draw_mode == dm_cpool && !pool.valid())
8268 return;
8269
8270 int c = start.truncate();
8271 mapscr* scr = Map.Scr(start, CurrentLayer);
8272 if (!scr) return;
8273
8274 int num_combos_width = 16 * Map.getViewSize();
8275 int num_combos_height = 11 * Map.getViewSize();
8276 int targetcombo = scr->data[c];
8277 int targetcset = scr->cset[c];
8278
8279 mark_save_dirty();
8280 Map.StartListCommand();
8281 if(key[KEY_LSHIFT] || key[KEY_RSHIFT])
8282 {
8283 for (int x = 0; x < num_combos_width; x++)
8284 {
8285 for (int y = 0; y < num_combos_height; y++)
8286 {
8287 ComboPosition pos = {x, y};
8288 int c = pos.truncate();
8289 mapscr* scr = Map.Scr(pos, CurrentLayer);
8290 if (!scr)
8291 continue;
8292
8293 if ((scr->cset[c]) == targetcset)
8294 {
8295 if(draw_mode == dm_cpool)
8296 pool.pick(cid,cs);
8297 Map.DoSetComboCommand(pos, -1, cs);
8298 }
8299 }
8300 }
8301 }
8302 else
8303 {
8304 for (int x = 0; x < num_combos_width; x++)
8305 {
8306 for (int y = 0; y < num_combos_height; y++)
8307 {
8308 ComboPosition pos = {x, y};
8309 int c = pos.truncate();
8310 mapscr* scr = Map.Scr(pos, CurrentLayer);
8311 if (!scr)
8312 continue;
8313
8314 if(((scr->data[c])==targetcombo) &&
8315 ((scr->cset[c])==targetcset))
8316 {
8317 if(draw_mode == dm_cpool)
8318 pool.pick(cid,cs);
8319 Map.DoSetComboCommand(pos, cid, cs);
8320 }
8321 }
8322 }
8323 }
8324 Map.FinishListCommand();
8325
8326 refresh(rMAP);
8327 }
8328
8329 static void draw_block(ComboPosition start, int32_t w, int32_t h)
8330 {
8331 int32_t cid = Combo;
8332 int8_t cs = CSet;
8333 if(draw_mode == dm_cpool)
8334 {
8335 combo_pool const& pool = combo_pools[combo_pool_pos];
8336 if(!pool.pick(cid,cs)) return;
8337 }
8338
8339 mapscr* scr = Map.Scr(start, CurrentLayer);
8340 if (!scr) return;
8341
8342 mark_save_dirty();
8343 Map.StartListCommand();
8344 for (int32_t y=0; y < h && y < 11*Map.getViewSize(); y++)
8345 for (int32_t x=0; x < w && x < 16*Map.getViewSize(); x++)
8346 {
8347 Map.DoSetComboCommand(start + ComboPosition{x, y}, cid+(y*4)+x, cs);
8348 }
8349
8350 Map.FinishListCommand();
8351 refresh(rMAP+rSCRMAP);
8352 }
8353
8354 static std::vector<ComboPosition> flood_filler(ComboPosition start_pos, bool allow_diagonal, std::function<bool(ComboPosition)> check)
8355 {
8356 std::vector<ComboPosition> seen, queue;
8357
8358 queue.push_back(start_pos);
8359 while (!queue.empty())
8360 {
8361 ComboPosition pos = queue.back();
8362 queue.pop_back();
8363 seen.push_back(pos);
8364
8365 ComboPosition pos2;
8366 #define FLOOD_FILLER_CHECK(dx, dy)\
8367 pos2 = pos + ComboPosition{dx, dy};\
8368 if (std::find(seen.begin(), seen.end(), pos2) == seen.end() && check(pos2))\
8369 queue.push_back(pos2);
8370
8371 FLOOD_FILLER_CHECK(0, 1);
8372 FLOOD_FILLER_CHECK(0, -1);
8373 FLOOD_FILLER_CHECK(1, 0);
8374 FLOOD_FILLER_CHECK(-1, 0);
8375
8376 if (allow_diagonal)
8377 {
8378 FLOOD_FILLER_CHECK(1, 1);
8379 FLOOD_FILLER_CHECK(1, -1);
8380 FLOOD_FILLER_CHECK(-1, 1);
8381 FLOOD_FILLER_CHECK(-1, -1);
8382 }
8383
8384 #undef FLOOD_FILLER_CHECK
8385 }
8386
8387 return seen;
8388 }
8389
8390 static void fill(int32_t targetcombo, int32_t targetcset, ComboPosition start_pos, bool allow_diagonal, bool only_cset)
8391 {
8392 bool rclick = gui_mouse_b() & 2;
8393 bool ignored_combo = false;
8394
8395 mapscr* scr = Map.ScrMakeValid(start_pos, CurrentLayer);
8396 if (!scr)
8397 return;
8398
8399 int num_combos_width = 16 * Map.getViewSize();
8400 int num_combos_height = 11 * Map.getViewSize();
8401
8402 auto combo_positions = flood_filler(start_pos, allow_diagonal, [&](ComboPosition pos){
8403 if (pos.x < 0 || pos.y < 0 || pos.x >= num_combos_width || pos.y >= num_combos_height)
8404 return false;
8405
8406 mapscr* scr = Map.Scr(pos, CurrentLayer);
8407 if (!scr || !scr->is_valid())
8408 return false;
8409
8410 int cid = scr->data[pos.truncate()];
8411 int cset = scr->cset[pos.truncate()];
8412
8413 if (draw_mode == dm_auto)
8414 {
8415 combo_auto const& cauto = combo_autos[combo_auto_pos];
8416
8417 ignored_combo = cauto.isIgnoredCombo(cid);
8418 if (rclick)
8419 {
8420 if (cauto.containsCombo(targetcombo))
8421 {
8422 if (!cauto.containsCombo(cid))
8423 return false;
8424 if (cauto.getType() == AUTOCOMBO_REPLACE && ignored_combo)
8425 return false;
8426 }
8427 else
8428 return false;
8429 }
8430 else
8431 {
8432 if (cid != targetcombo && !ignored_combo)
8433 return false;
8434 if (cauto.getType() == AUTOCOMBO_REPLACE && !ignored_combo)
8435 return false;
8436 }
8437
8438 if (cset != targetcset && !ignored_combo)
8439 return false;
8440 }
8441 else
8442 {
8443 if(!only_cset)
8444 {
8445 if (cid != targetcombo)
8446 return false;
8447 }
8448
8449 if (cset != targetcset)
8450 return false;
8451 }
8452
8453 return true;
8454 });
8455
8456 for (auto& pos : combo_positions)
8457 {
8458 int32_t cid = Combo;
8459 int8_t cs = CSet;
8460
8461 if (draw_mode == dm_cpool)
8462 {
8463 combo_pool const& pool = combo_pools[combo_pool_pos];
8464 if (!pool.pick(cid, cs)) continue;
8465 }
8466 else if (draw_mode == dm_auto)
8467 {
8468 combo_auto const& cauto = combo_autos[combo_auto_pos];
8469 if (!cauto.valid())
8470 continue;
8471 if (!rclick && (cauto.containsCombo(targetcombo) && !ignored_combo))
8472 continue;
8473 if (rclick && cauto.getEraseCombo() == targetcombo)
8474 continue;
8475 }
8476
8477 if (draw_mode == dm_auto)
8478 draw_autocombo(pos, rclick);
8479 else
8480 Map.DoSetComboCommand(pos, only_cset ? -1 : cid, cs);
8481 }
8482 }
8483
8484 static void fill_flag(int32_t targetflag, ComboPosition start_pos, bool allow_diagonal)
8485 {
8486 mapscr* scr = Map.ScrMakeValid(start_pos, CurrentLayer);
8487 if (!scr)
8488 return;
8489
8490 int num_combos_width = 16 * Map.getViewSize();
8491 int num_combos_height = 11 * Map.getViewSize();
8492
8493 auto combo_positions = flood_filler(start_pos, allow_diagonal, [&](ComboPosition pos){
8494 if (pos.x < 0 || pos.y < 0 || pos.x >= num_combos_width || pos.y >= num_combos_height)
8495 return false;
8496
8497 mapscr* scr = Map.Scr(pos, CurrentLayer);
8498 if (!scr || !scr->is_valid())
8499 return false;
8500
8501 if (scr->sflag[pos.truncate()] != targetflag)
8502 return false;
8503
8504 return true;
8505 });
8506
8507 for (auto& pos : combo_positions)
8508 Map.DoSetFlagCommand(pos, Flag);
8509 }
8510
8511 static void fill2(int32_t targetcombo, int32_t targetcset, ComboPosition pos, int32_t dir, int32_t diagonal, bool only_cset)
8512 {
8513 mapscr* scr = Map.Scr(pos, CurrentLayer);
8514 if (!scr || !scr->is_valid())
8515 return;
8516
8517 int cid = scr->data[pos.truncate()];
8518 int cset = scr->cset[pos.truncate()];
8519
8520 if (!only_cset)
8521 {
8522 if (cid == targetcombo)
8523 return;
8524 }
8525
8526 if (cset == targetcset)
8527 return;
8528
8529 cid = Combo;
8530 int8_t cs = CSet;
8531 if(draw_mode == dm_cpool)
8532 {
8533 combo_pool const& pool = combo_pools[combo_pool_pos];
8534 if(!pool.pick(cid,cs)) return;
8535 }
8536
8537 Map.DoSetComboCommand(pos, only_cset ? -1 : cid, cs);
8538
8539 int num_combos_width = 16 * Map.getViewSize();
8540 int num_combos_height = 11 * Map.getViewSize();
8541
8542 if (pos.y > 0 && dir != down)
8543 fill2(targetcombo, targetcset, pos + ComboPosition{0, -1}, up, diagonal, only_cset);
8544 if (pos.y < num_combos_height-1 && dir != up)
8545 fill2(targetcombo, targetcset, pos + ComboPosition{0, 1}, down, diagonal, only_cset);
8546 if (pos.x > 0 && dir != right)
8547 fill2(targetcombo, targetcset, pos + ComboPosition{-1, 0}, left, diagonal, only_cset);
8548 if (pos.x < num_combos_width-1 && dir != left)
8549 fill2(targetcombo, targetcset, pos + ComboPosition{1, 0}, right, diagonal, only_cset);
8550
8551 if (diagonal == 1)
8552 {
8553 if (pos.y > 0 && pos.x > 0 && dir != r_down)
8554 fill2(targetcombo, targetcset, pos + ComboPosition{-1, -1}, l_up, diagonal, only_cset);
8555 if (pos.y < num_combos_height-1 && pos.x < num_combos_width-1 && dir != l_up)
8556 fill2(targetcombo, targetcset, pos + ComboPosition{1, 1}, r_down, diagonal, only_cset);
8557 if (pos.x > 0 && pos.y < num_combos_height-1 && dir != r_up)
8558 fill2(targetcombo, targetcset, pos + ComboPosition{-1, 1}, l_down, diagonal, only_cset);
8559 if (pos.x < num_combos_width-1 && pos.y > 0 && dir != l_down)
8560 fill2(targetcombo, targetcset, pos + ComboPosition{1, -1}, r_up, diagonal, only_cset);
8561 }
8562 }
8563
8564
8565 enum SnapMode
8566 {
8567 SNAP_NONE, SNAP_HALF, SNAP_WHOLE
8568 };
8569 static void snap_xy(int& x, int& y, SnapMode mode, roundType rounding, optional<int> max_x = nullopt, optional<int> max_y = nullopt)
8570 {
8571 if(mode == SNAP_NONE)
8572 {
8573 if(max_x) x = vbound(x,*max_x,0);
8574 if(max_y) y = vbound(y,*max_y,0);
8575 return;
8576 }
8577 int xoff = 0, yoff = 0;
8578 switch(rounding)
8579 {
8580 case ROUND_TO_0:
8581 rounding = ROUND_DOWN;
8582 break;
8583 case ROUND_AWAY_0:
8584 rounding = ROUND_UP;
8585 break;
8586 }
8587 int r = 0;
8588 switch(mode)
8589 {
8590 case SNAP_HALF:
8591 r = 8;
8592 break;
8593 case SNAP_WHOLE:
8594 r = 16;
8595 break;
8596 }
8597 assert(r > 0);
8598 // r must be a power of 2, for bitwise reasons
8599 switch(rounding)
8600 {
8601 case ROUND_DOWN:
8602 break;
8603 case ROUND_UP:
8604 xoff = ((x & (r-1)) ? r : 0);
8605 yoff = ((y & (r-1)) ? r : 0);
8606 break;
8607 case ROUND_NEAREST:
8608 xoff = ((x & (r-1)) >= (r/2) ? r : 0);
8609 yoff = ((y & (r-1)) >= (r/2) ? r : 0);
8610 break;
8611 }
8612 x = (x & ~(r-1)) + xoff;
8613 y = (y & ~(r-1)) + yoff;
8614 if(max_x && x >= *max_x) x = *max_x-r;
8615 else if(max_x && x < 0) x = 0;
8616 if(max_y && y >= *max_y) y = *max_y-r;
8617 else if(max_y && y < 0) y = 0;
8618 }
8619
8620 static void doxypos(byte &px2, byte &py2, int32_t color, SnapMode snap_mode,
8621 SnapMode shift_mode, bool immediately, int32_t cursoroffx,
8622 int32_t cursoroffy, int32_t iconw, int32_t iconh)
8623 {
8624 int32_t tempcb=ComboBrush;
8625 ComboBrush=0;
8626 MouseSprite::set(ZQM_POINT_BOX);
8627
8628 int viz_off_x = (active_visible_screen ? active_visible_screen->dx * 256 : 0);
8629 int viz_off_y = (active_visible_screen ? active_visible_screen->dy * 176 : 0);
8630
8631 int32_t oldpx=px2, oldpy=py2;
8632 int32_t startxint=mapscreen_x+(showedges?int32_t(16*mapscreen_single_scale):0);
8633 int32_t startyint=mapscreen_y+(showedges?int32_t(16*mapscreen_single_scale):0);
8634 showxypos_x=px2 + viz_off_x;
8635 showxypos_y=py2 + viz_off_y;
8636 showxypos_w=iconw;
8637 showxypos_h=iconh;
8638 showxypos_color=vc(color);
8639 showxypos_icon=!showxypos_dummy;
8640 bool canedit=false;
8641 bool done=false;
8642
8643 clear_tooltip();
8644
8645 while(!done && (!(gui_mouse_b()&2) || immediately))
8646 {
8647 if(!gui_mouse_b() || immediately)
8648 {
8649 canedit=true;
8650 }
8651
8652 // TODO: would be nice if these bounds were based on the individual screen.
8653 if(canedit && gui_mouse_b()==1 && isinRect(gui_mouse_x(),gui_mouse_y(),startxint,startyint,(startxint+(256*mapscreen_screenunit_scale)-1),(startyint+(176*mapscreen_screenunit_scale)-1)))
8654 {
8655 set_mouse_range(startxint,startyint,int32_t(startxint+(256*mapscreen_screenunit_scale)-1),int32_t(startyint+(176*mapscreen_screenunit_scale)-1));
8656
8657 double offx = 0, offy = 0;
8658 roundType rounding = ROUND_DOWN;
8659 if(DragCenterOfSquares)
8660 {
8661 offx -= iconw*mapscreen_single_scale/2;
8662 offy -= iconh*mapscreen_single_scale/2;
8663 rounding = ROUND_NEAREST;
8664 }
8665 int32_t x, y;
8666 do
8667 {
8668 poll_keyboard(); // re-check shift key!
8669 x=int32_t((gui_mouse_x()-startxint+offx)/mapscreen_single_scale)-cursoroffx;
8670 y=int32_t((gui_mouse_y()-startyint+offy)/mapscreen_single_scale)-cursoroffy;
8671 showxypos_cursor_icon=true;
8672 showxypos_cursor_color = showxypos_color;
8673 auto _mode = (key[KEY_LSHIFT] || key[KEY_RSHIFT]) ? shift_mode : snap_mode;
8674 showxypos_cursor_x = x-viz_off_x;
8675 showxypos_cursor_y = y-viz_off_y;
8676 snap_xy(showxypos_cursor_x, showxypos_cursor_y, _mode, rounding, 256, 176);
8677 showxypos_cursor_x += viz_off_x;
8678 showxypos_cursor_y += viz_off_y;
8679 custom_vsync();
8680 refresh(rALL | rNOCURSOR);
8681 int32_t xpos[2], ypos[2];
8682 int32_t x1,y1,x2,y2;
8683
8684 char b1[200] = {0};
8685 char b2[200] = {0};
8686 if(showxypos_dummy)
8687 strcpy(b1, "DUMMY MEASURING");
8688 else sprintf(b1, "%d %d",oldpx,oldpy);
8689 sprintf(b2, "%d %d (%d %d)",x-viz_off_x,y-viz_off_y,showxypos_cursor_x-viz_off_x,showxypos_cursor_y-viz_off_y);
8690
8691 int len[2] = {text_length(font,b1),text_length(font,b2)};
8692
8693 if(is_compact)
8694 {
8695 xpos[0] = 4;
8696 ypos[0] = layer_panel.y - 21;
8697 xpos[1] = xpos[0];
8698 ypos[1] = ypos[0]+10;
8699 }
8700 else
8701 {
8702 xpos[0] = 450;
8703 ypos[0] = 405;
8704 xpos[1] = xpos[0];
8705 ypos[1] = ypos[0]+10;
8706 }
8707
8708 x1 = xpos[0];
8709 y1 = ypos[0];
8710 x2 = xpos[0];
8711 y2 = ypos[0];
8712 for(auto q = 0; q < 2; ++q)
8713 {
8714 if(xpos[q] < x1)
8715 x1 = xpos[q];
8716 if(ypos[q] < y1)
8717 y1 = ypos[q];
8718 if(ypos[q] > y2)
8719 y2 = ypos[q];
8720 if(xpos[q] + len[q] > x2)
8721 x2 = xpos[q] + len[q];
8722 }
8723 x1 -= 4;
8724 y1 -= 2;
8725 y2 += text_height(font)+2;
8726
8727 auto minx = zc_min(xpos[0],xpos[1]);
8728 auto miny = zc_min(ypos[0],ypos[1]);
8729 rectfill(screen,x1,y1,x2,y2,vc(0));
8730 textprintf_ex(screen,font,xpos[0],ypos[0],vc(15),vc(0),"%s",b1);
8731 textprintf_ex(screen,font,xpos[1],ypos[1],vc(15),vc(0),"%s",b2);
8732 update_hw_screen();
8733 }
8734 while(gui_mouse_b()==1);
8735
8736 if(gui_mouse_b()==0)
8737 {
8738 auto _mode = (key[KEY_LSHIFT] || key[KEY_RSHIFT]) ? shift_mode : snap_mode;
8739 int x2 = vbound(x-viz_off_x,0,255);
8740 int y2 = vbound(y-viz_off_y,0,175);
8741 snap_xy(x2, y2, _mode, rounding, 256, 176);
8742 px2=byte(x2);
8743 py2=byte(y2);
8744 }
8745
8746 set_mouse_range(0,0,zq_screen_w-1,zq_screen_h-1);
8747 done=true;
8748 }
8749
8750 if(keypressed())
8751 {
8752 switch(readkey()>>8)
8753 {
8754 case KEY_ESC:
8755 case KEY_ENTER:
8756 goto finished;
8757 }
8758 }
8759
8760 custom_vsync();
8761 refresh(rALL | rNOCURSOR);
8762 }
8763
8764 finished:
8765 MouseSprite::set(ZQM_NORMAL);
8766 refresh(rMAP+rMENU);
8767
8768 while(gui_mouse_b())
8769 {
8770 /* do nothing */
8771 rest(1);
8772 }
8773
8774 showxypos_x=-1000;
8775 showxypos_y=-1000;
8776 showxypos_color=-1000;
8777 showxypos_ffc=-1000;
8778 showxypos_icon=false;
8779 showxypos_cursor_x=-1000;
8780 showxypos_cursor_y=-1000;
8781 showxypos_cursor_icon=false;
8782 showxypos_cursor_color=-1000;
8783 showxypos_dummy=false;
8784
8785 if(px2!=oldpx||py2!=oldpy)
8786 {
8787 mark_save_dirty();
8788 }
8789
8790 ComboBrush=tempcb;
8791 }
8792 static void doxypos(byte &px2,byte &py2,int32_t color,SnapMode snap_mode, optional<SnapMode> shift_mode = nullopt)
8793 {
8794 doxypos(px2,py2,color,snap_mode,shift_mode ? *shift_mode : snap_mode,false,0,0,16,16);
8795 }
8796
8797 bool placing_flags = false;
8798 void doflags()
8799 {
8800 placing_flags = true;
8801 int of=Flags;
8802 Flags=cFLAGS;
8803 refresh(rMAP | rNOCURSOR);
8804
8805 bool canedit=false;
8806 bool didShift = false;
8807 int tFlag = Flag;
8808 while(!(gui_mouse_b()&2) && !handle_close_btn_quit())
8809 {
8810 int x=gui_mouse_x();
8811 int y=gui_mouse_y();
8812 double startx=mapscreen_x+(showedges?(16*mapscreen_single_scale):0);
8813 double starty=mapscreen_y+(showedges?(16*mapscreen_single_scale):0);
8814 int startxint=mapscreen_x+(showedges?int(16*mapscreen_single_scale):0);
8815 int startyint=mapscreen_y+(showedges?int(16*mapscreen_single_scale):0);
8816 int cx=(x-startxint)/int(16*mapscreen_single_scale);
8817 int cy=(y-startyint)/int(16*mapscreen_single_scale);
8818 ComboPosition combo_pos = {cx, cy};
8819 int c = combo_pos.truncate();
8820
8821 if(!gui_mouse_b())
8822 canedit=true;
8823 bool shift = key[KEY_LSHIFT] || key[KEY_RSHIFT];
8824
8825 if(canedit && gui_mouse_b()==1 && isinRect(x,y,startxint,startyint,int(startx+(256*mapscreen_screenunit_scale)-1),int(starty+(176*mapscreen_screenunit_scale)-1)))
8826 {
8827 mapscr* cur_scr = Map.Scr(combo_pos, CurrentLayer);
8828 if (!cur_scr) continue;
8829
8830 Map.setCurrScr(Map.getScreenForPosition(combo_pos));
8831
8832 if(key[KEY_ALT]||key[KEY_ALTGR])
8833 Flag = cur_scr->sflag[c];
8834 else
8835 {
8836 mark_save_dirty();
8837 int tflag = Flag;
8838 if(shift)
8839 Flag = mfNONE;
8840 if(CurrentLayer!=0)
8841 {
8842 // Notify if they are using a flag that doesn't work on this layer.
8843 if(!skipLayerWarning && ((Flag >= mfTRAP_H && Flag < mfPUSHD) || (Flag == mfFAIRY) || (Flag == mfMAGICFAIRY)
8844 || (Flag == mfALLFAIRY) || (Flag == mfRAFT) || (Flag == mfRAFT_BRANCH)
8845 || (Flag == mfDIVE_ITEM) || (Flag == mfARMOS_SECRET) || (Flag == mfNOENEMY)
8846 || (Flag == mfZELDA)))
8847 {
8848 InfoDialog("Notice","You are currently working on layer "
8849 +to_string(CurrentLayer)
8850 +". This combo flag does not function on layers above '0'.").show();
8851 }
8852 if(!skipLayerWarning && CurrentLayer > 2 &&
8853 ((Flag == mfBLOCKHOLE) || (Flag >= mfPUSHD && Flag < mfNOBLOCKS)
8854 || (Flag == mfPUSHUD) || (Flag == mfPUSH4)))
8855 {
8856 InfoDialog("Notice","You are currently working on layer "
8857 +to_string(CurrentLayer)
8858 +". This combo flag does not function on layers above '2'.").show();
8859 }
8860 }
8861 if(CHECK_CTRL_CMD)
8862 {
8863 switch(fill_type)
8864 {
8865 case 0:
8866 flood_flag();
8867 break;
8868
8869 case 1:
8870 case 3:
8871 fill_4_flag();
8872 break;
8873
8874 case 2:
8875 case 4:
8876 fill_8_flag();
8877 break;
8878 }
8879 }
8880 else
8881 {
8882 Map.DoSetFlagCommand(combo_pos, Flag);
8883 }
8884 Flag = tflag;
8885 }
8886 }
8887
8888 if(mouse_z)
8889 {
8890 for(int i=0; i<abs(mouse_z); ++i)
8891 {
8892 if(mouse_z>0)
8893 onIncreaseFlag();
8894 else
8895 onDecreaseFlag();
8896 }
8897
8898 position_mouse_z(0);
8899 }
8900
8901 if(keypressed())
8902 {
8903 int k = readkey();
8904 switch(k>>8)
8905 {
8906 case KEY_ESC:
8907 case KEY_ENTER:
8908 goto finished;
8909 }
8910 object_message(dialogs+1, MSG_XCHAR, k);
8911 Flags=cFLAGS;
8912 }
8913
8914 MouseSprite::set(ZQM_FLAG_0+(shift?0:Flag%16));
8915
8916 refresh(rALL | rCLEAR | rNOCURSOR);
8917 custom_vsync();
8918 }
8919
8920 finished:
8921 Flags=of;
8922 placing_flags = false;
8923 MouseSprite::set(ZQM_NORMAL);
8924 refresh(rMAP+rMENU);
8925
8926 while(gui_mouse_b())
8927 {
8928 /* do nothing */
8929 rest(1);
8930 }
8931 }
8932
8933 // Drag FFCs around
8934 static void moveffc(int i, int cx, int cy)
8935 {
8936 mapscr* scr = active_visible_screen->scr;
8937 int screen = active_visible_screen->screen;
8938
8939 int32_t ffx = vbound(scr->ffcs[i].x.getFloor(),0,240);
8940 int32_t ffy = vbound(scr->ffcs[i].y.getFloor(),0,160);
8941 int32_t offx = ffx, offy = ffy;
8942 showxypos_ffc = i;
8943 doxypos((byte&)ffx,(byte&)ffy,15,SNAP_HALF,SNAP_NONE,true,0,0,(scr->ffTileWidth(i)*16),(scr->ffTileHeight(i)*16));
8944 if(ffx > 240) ffx = 240;
8945 if(ffy > 160) ffy = 160;
8946 if((ffx != offx) || (ffy != offy))
8947 {
8948 auto set_ffc_data = set_ffc_command::create_data(scr->ffcs[i]);
8949 set_ffc_data.x = ffx;
8950 set_ffc_data.y = ffy;
8951 Map.DoSetFFCCommand(Map.getCurrMap(), screen, i, set_ffc_data);
8952 mark_save_dirty();
8953 }
8954 }
8955
8956 void set_brush_width(int32_t width);
8957 void set_brush_height(int32_t height);
8958
8959 int32_t set_brush_width_1()
8960 {
8961 set_brush_width(1);
8962 return D_O_K;
8963 }
8964 int32_t set_brush_width_2()
8965 {
8966 set_brush_width(2);
8967 return D_O_K;
8968 }
8969 int32_t set_brush_width_3()
8970 {
8971 set_brush_width(3);
8972 return D_O_K;
8973 }
8974 int32_t set_brush_width_4()
8975 {
8976 set_brush_width(4);
8977 return D_O_K;
8978 }
8979 int32_t set_brush_width_5()
8980 {
8981 set_brush_width(5);
8982 return D_O_K;
8983 }
8984 int32_t set_brush_width_6()
8985 {
8986 set_brush_width(6);
8987 return D_O_K;
8988 }
8989 int32_t set_brush_width_7()
8990 {
8991 set_brush_width(7);
8992 return D_O_K;
8993 }
8994 int32_t set_brush_width_8()
8995 {
8996 set_brush_width(8);
8997 return D_O_K;
8998 }
8999 int32_t set_brush_width_9()
9000 {
9001 set_brush_width(9);
9002 return D_O_K;
9003 }
9004 int32_t set_brush_width_10()
9005 {
9006 set_brush_width(10);
9007 return D_O_K;
9008 }
9009 int32_t set_brush_width_11()
9010 {
9011 set_brush_width(11);
9012 return D_O_K;
9013 }
9014 int32_t set_brush_width_12()
9015 {
9016 set_brush_width(12);
9017 return D_O_K;
9018 }
9019 int32_t set_brush_width_13()
9020 {
9021 set_brush_width(13);
9022 return D_O_K;
9023 }
9024 int32_t set_brush_width_14()
9025 {
9026 set_brush_width(14);
9027 return D_O_K;
9028 }
9029 int32_t set_brush_width_15()
9030 {
9031 set_brush_width(15);
9032 return D_O_K;
9033 }
9034 int32_t set_brush_width_16()
9035 {
9036 set_brush_width(16);
9037 return D_O_K;
9038 }
9039
9040 int32_t set_brush_height_1()
9041 {
9042 set_brush_height(1);
9043 return D_O_K;
9044 }
9045 int32_t set_brush_height_2()
9046 {
9047 set_brush_height(2);
9048 return D_O_K;
9049 }
9050 int32_t set_brush_height_3()
9051 {
9052 set_brush_height(3);
9053 return D_O_K;
9054 }
9055 int32_t set_brush_height_4()
9056 {
9057 set_brush_height(4);
9058 return D_O_K;
9059 }
9060 int32_t set_brush_height_5()
9061 {
9062 set_brush_height(5);
9063 return D_O_K;
9064 }
9065 int32_t set_brush_height_6()
9066 {
9067 set_brush_height(6);
9068 return D_O_K;
9069 }
9070 int32_t set_brush_height_7()
9071 {
9072 set_brush_height(7);
9073 return D_O_K;
9074 }
9075 int32_t set_brush_height_8()
9076 {
9077 set_brush_height(8);
9078 return D_O_K;
9079 }
9080 int32_t set_brush_height_9()
9081 {
9082 set_brush_height(9);
9083 return D_O_K;
9084 }
9085 int32_t set_brush_height_10()
9086 {
9087 set_brush_height(10);
9088 return D_O_K;
9089 }
9090 int32_t set_brush_height_11()
9091 {
9092 set_brush_height(11);
9093 return D_O_K;
9094 }
9095
9096
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu brush_width_menu
9097 204 {
9098
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "1", set_brush_width_1 },
9099
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2", set_brush_width_2 },
9100
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "3", set_brush_width_3 },
9101
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "4", set_brush_width_4 },
9102
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "5", set_brush_width_5 },
9103
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "6", set_brush_width_6 },
9104
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "7", set_brush_width_7 },
9105
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "8", set_brush_width_8 },
9106
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "9", set_brush_width_9 },
9107
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "10", set_brush_width_10 },
9108
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "11", set_brush_width_11 },
9109
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "12", set_brush_width_12 },
9110
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "13", set_brush_width_13 },
9111
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "14", set_brush_width_14 },
9112
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "15", set_brush_width_15 },
9113
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "16", set_brush_width_16 },
9114 };
9115
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu brush_height_menu
9116 144 {
9117
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "1", set_brush_height_1 },
9118
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2", set_brush_height_2 },
9119
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "3", set_brush_height_3 },
9120
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "4", set_brush_height_4 },
9121
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "5", set_brush_height_5 },
9122
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "6", set_brush_height_6 },
9123
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "7", set_brush_height_7 },
9124
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "8", set_brush_height_8 },
9125
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "9", set_brush_height_9 },
9126
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "10", set_brush_height_10 },
9127
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "11", set_brush_height_11 },
9128 };
9129
9130 int toggle_autobrush();
9131 int toggle_combobrush();
9132 int toggle_floatbrush();
9133 enum
9134 {
9135 MENUID_BRUSH_AUTOBRUSH,
9136 MENUID_BRUSH_WIDTH,
9137 MENUID_BRUSH_HEIGHT,
9138 MENUID_BRUSH_COMBOBRUSH,
9139 MENUID_BRUSH_FLOATBRUSH,
9140 };
9141
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu brush_menu
9142 72 {
9143
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "AutoBrush", toggle_autobrush, MENUID_BRUSH_AUTOBRUSH },
9144
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Brush Width ", &brush_width_menu, MENUID_BRUSH_WIDTH },
9145
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Brush Height ", &brush_height_menu, MENUID_BRUSH_HEIGHT },
9146
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "ComboBrush", toggle_combobrush, MENUID_BRUSH_COMBOBRUSH },
9147
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "FloatBrush", toggle_floatbrush, MENUID_BRUSH_FLOATBRUSH },
9148 };
9149 int toggle_autobrush()
9150 {
9151 AutoBrush = AutoBrush ? 0 : 1;
9152 BrushWidth = BrushHeight = 1;
9153 brush_menu.select_uid(MENUID_BRUSH_AUTOBRUSH, AutoBrush);
9154 brush_menu.disable_uid(MENUID_BRUSH_WIDTH, AutoBrush);
9155 brush_menu.disable_uid(MENUID_BRUSH_HEIGHT, AutoBrush);
9156 zc_set_config("zquest","autobrush",AutoBrush);
9157 return D_O_K;
9158 }
9159 int toggle_combobrush()
9160 {
9161 ComboBrush = ComboBrush ? 0 : 1;
9162 brush_menu.select_uid(MENUID_BRUSH_COMBOBRUSH, ComboBrush);
9163 zc_set_config("zquest","combo_brush",ComboBrush);
9164 return D_O_K;
9165 }
9166 int toggle_floatbrush()
9167 {
9168 FloatBrush = FloatBrush ? 0 : 1;
9169 brush_menu.select_uid(MENUID_BRUSH_FLOATBRUSH, FloatBrush);
9170 zc_set_config("zquest","float_brush",FloatBrush);
9171 return D_O_K;
9172 }
9173
9174 int32_t set_flood();
9175 int32_t set_fill_4();
9176 int32_t set_fill_8();
9177 int32_t set_fill2_4();
9178 int32_t set_fill2_8();
9179
9180 // Sets every combo.
9181 void flood()
9182 {
9183 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9184 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9185 if (!scr || !scr->is_valid())
9186 return;
9187
9188 mark_save_dirty();
9189
9190 bool include_combos = !(key[KEY_LSHIFT]||key[KEY_RSHIFT]);
9191
9192 int num_combos_width = 16 * Map.getViewSize();
9193 int num_combos_height = 11 * Map.getViewSize();
9194
9195 Map.StartListCommand();
9196 for (int x = 0; x < num_combos_width; x++)
9197 {
9198 for (int y = 0; y < num_combos_height; y++)
9199 {
9200 ComboPosition pos = {x, y};
9201 mapscr* scr = Map.Scr(pos, CurrentLayer);
9202 if (!scr || !scr->is_valid())
9203 continue;
9204
9205 if (draw_mode == dm_auto)
9206 draw_autocombo(pos, gui_mouse_b() & 2);
9207 else
9208 Map.DoSetComboCommand(pos, include_combos ? Combo : -1, CSet);
9209 }
9210 }
9211 Map.FinishListCommand();
9212
9213 refresh(rMAP+rSCRMAP);
9214 }
9215 void flood_flag()
9216 {
9217 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9218 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9219 if (!scr || !scr->is_valid())
9220 return;
9221
9222 mark_save_dirty();
9223
9224 int num_combos_width = 16 * Map.getViewSize();
9225 int num_combos_height = 11 * Map.getViewSize();
9226
9227 Map.StartListCommand();
9228 for (int x = 0; x < num_combos_width; x++)
9229 {
9230 for (int y = 0; y < num_combos_height; y++)
9231 {
9232 ComboPosition pos = {x, y};
9233 mapscr* scr = Map.Scr(pos, CurrentLayer);
9234 if (!scr || !scr->is_valid())
9235 continue;
9236
9237 Map.DoSetFlagCommand(pos, Flag);
9238 }
9239 }
9240 Map.FinishListCommand();
9241
9242 refresh(rMAP+rSCRMAP);
9243 }
9244
9245 void fill_4()
9246 {
9247 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9248 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9249 if (!scr)
9250 return;
9251
9252 int c = pos.truncate();
9253 if (draw_mode == dm_cpool || draw_mode == dm_auto
9254 || (scr->cset[c]!=CSet || (scr->data[c]!=Combo && !(key[KEY_LSHIFT]||key[KEY_RSHIFT]))))
9255 {
9256 mark_save_dirty();
9257
9258 Map.StartListCommand();
9259 if (draw_mode == dm_auto && (combo_autos[combo_auto_pos].getType() == AUTOCOMBO_FENCE ||
9260 combo_autos[combo_auto_pos].getType() == AUTOCOMBO_Z4))
9261 {
9262 draw_autocombo_command(pos);
9263 }
9264 else
9265 {
9266 bool allow_diagonal = false;
9267 fill(scr->data[c], scr->cset[c], pos, allow_diagonal, (key[KEY_LSHIFT] || key[KEY_RSHIFT]));
9268 }
9269 Map.FinishListCommand();
9270 refresh(rMAP+rSCRMAP);
9271 }
9272 }
9273 void fill_4_flag()
9274 {
9275 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9276 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9277 if (!scr)
9278 return;
9279
9280 int flag = scr->sflag[pos.truncate()];
9281 if (flag != Flag)
9282 {
9283 mark_save_dirty();
9284
9285 Map.StartListCommand();
9286 bool allow_diagonal = false;
9287 fill_flag(flag, pos, allow_diagonal);
9288 Map.FinishListCommand();
9289 refresh(rMAP+rSCRMAP);
9290 }
9291 }
9292 void fill_8()
9293 {
9294 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9295 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9296 if (!scr)
9297 return;
9298
9299 int c = pos.truncate();
9300 if (draw_mode == dm_cpool || draw_mode == dm_auto
9301 || (scr->cset[c] != CSet ||
9302 (scr->data[c] != Combo &&
9303 !(key[KEY_LSHIFT]||key[KEY_RSHIFT]))))
9304 {
9305 mark_save_dirty();
9306
9307 Map.StartListCommand();
9308 bool allow_diagonal = true;
9309 fill(scr->data[c], scr->cset[c], pos, allow_diagonal, (key[KEY_LSHIFT]||key[KEY_RSHIFT]));
9310 Map.FinishListCommand();
9311
9312 refresh(rMAP+rSCRMAP);
9313 }
9314 }
9315 void fill_8_flag()
9316 {
9317 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9318 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9319 if (!scr)
9320 return;
9321
9322 int flag = scr->sflag[pos.truncate()];
9323 if (flag != Flag)
9324 {
9325 mark_save_dirty();
9326
9327 Map.StartListCommand();
9328 bool allow_diagonal = true;
9329 fill_flag(flag, pos, allow_diagonal);
9330 Map.FinishListCommand();
9331 refresh(rMAP+rSCRMAP);
9332 }
9333 }
9334
9335 void fill2_4()
9336 {
9337 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9338 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9339 if (!scr)
9340 return;
9341
9342 mark_save_dirty();
9343
9344 Map.StartListCommand();
9345 fill2(Combo, CSet, pos, 255, 0, (key[KEY_LSHIFT]||key[KEY_RSHIFT]));
9346 Map.FinishListCommand();
9347 refresh(rMAP+rSCRMAP);
9348 }
9349
9350 void fill2_8()
9351 {
9352 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9353 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9354 if (!scr)
9355 return;
9356
9357 mark_save_dirty();
9358
9359 Map.StartListCommand();
9360 fill2(Combo, CSet, pos, 255, 1, (key[KEY_LSHIFT]||key[KEY_RSHIFT]));
9361 Map.FinishListCommand();
9362
9363 refresh(rMAP+rSCRMAP);
9364 }
9365
9366
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu fill_menu
9367 72 {
9368
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Flood", set_flood, 0 },
9369
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fill (4-way)", set_fill_4, 1 },
9370
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fill (8-way)", set_fill_8, 2 },
9371
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fill2 (4-way)", set_fill2_4, 3 },
9372
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fill2 (8-way)", set_fill2_8, 4 },
9373 };
9374 void set_filltype(int ty)
9375 {
9376 fill_type = ty;
9377 fill_menu.select_only_uid(ty);
9378 }
9379
9380 int32_t set_flood()
9381 {
9382 set_filltype(0);
9383 return D_O_K;
9384 }
9385
9386 int32_t set_fill_4()
9387 {
9388 set_filltype(1);
9389 return D_O_K;
9390 }
9391
9392 int32_t set_fill_8()
9393 {
9394 set_filltype(2);
9395 return D_O_K;
9396 }
9397
9398 int32_t set_fill2_4()
9399 {
9400 set_filltype(3);
9401 return D_O_K;
9402 }
9403
9404 int32_t set_fill2_8()
9405 {
9406 set_filltype(4);
9407 return D_O_K;
9408 }
9409
9410 int32_t draw_block_1_2()
9411 {
9412 draw_block(mouse_combo_pos,1,2);
9413 return D_O_K;
9414 }
9415
9416 int32_t draw_block_2_1()
9417 {
9418 draw_block(mouse_combo_pos,2,1);
9419 return D_O_K;
9420 }
9421
9422 int32_t draw_block_2_2()
9423 {
9424 draw_block(mouse_combo_pos,2,2);
9425 return D_O_K;
9426 }
9427
9428 int32_t draw_block_2_3()
9429 {
9430 draw_block(mouse_combo_pos,2,3);
9431 return D_O_K;
9432 }
9433
9434 int32_t draw_block_3_2()
9435 {
9436 draw_block(mouse_combo_pos,3,2);
9437 return D_O_K;
9438 }
9439
9440 int32_t draw_block_3_3()
9441 {
9442 draw_block(mouse_combo_pos,3,3);
9443 return D_O_K;
9444 }
9445
9446 int32_t draw_block_4_2()
9447 {
9448 draw_block(mouse_combo_pos,4,2);
9449 return D_O_K;
9450 }
9451
9452 int32_t draw_block_4_4()
9453 {
9454 draw_block(mouse_combo_pos,4,4);
9455 return D_O_K;
9456 }
9457
9458
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu draw_block_menu
9459 108 {
9460
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "1x2", draw_block_1_2 },
9461
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2x1", draw_block_2_1 },
9462
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2x2", draw_block_2_2 },
9463
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2x3", draw_block_2_3 },
9464
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "3x2", draw_block_3_2 },
9465
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "3x3", draw_block_3_3 },
9466
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "4x2", draw_block_4_2 },
9467
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "4x4", draw_block_4_4 },
9468 };
9469
9470
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu paste_screen_menu
9471 60 {
9472
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste", onPaste },
9473
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste All", onPasteAll },
9474
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste to All", onPasteToAll },
9475
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste All to All", onPasteAllToAll },
9476 };
9477
9478 int32_t scrollto_cmb(int32_t cid)
9479 {
9480 auto& sqr = combolist[current_combolist];
9481 int32_t res = vbound(cid-(sqr.w*sqr.h/2),0,MAXCOMBOS-(sqr.w*sqr.h));
9482 res -= res%sqr.w;
9483 return res;
9484 }
9485 int32_t scrollto_alias(int32_t alid)
9486 {
9487 auto& sqr = comboaliaslist[current_comboalist];
9488 int32_t res = vbound(alid-(sqr.w*sqr.h/2),0,MAXCOMBOALIASES-(sqr.w*sqr.h));
9489 res -= res%sqr.w;
9490 return res;
9491 }
9492
9493 int32_t scrollto_cpool(int32_t cpid)
9494 {
9495 auto& sqr = comboaliaslist[current_cpoollist];
9496 int32_t res = vbound(cpid-(sqr.w*sqr.h/2),0,MAXCOMBOPOOLS-(sqr.w*sqr.h));
9497 res -= res%sqr.w;
9498 return res;
9499 }
9500
9501 int32_t scrollto_cauto(int32_t caid)
9502 {
9503 auto& sqr = comboaliaslist[current_cautolist];
9504 int32_t res = vbound(caid - (sqr.w * sqr.h / 2), 0, MAXCOMBOPOOLS - (sqr.w * sqr.h));
9505 res -= res % sqr.w;
9506 return res;
9507 }
9508
9509 void add_favorite_combo_block(int32_t favind, int32_t cid, bool force)
9510 {
9511 int32_t w = vbound(BrushWidth, 1, 4);
9512 int32_t h = vbound(BrushHeight, 1, 7);
9513 for (int32_t xi = 0; xi < w; ++xi)
9514 {
9515 for (int32_t yi = 0; yi < h; ++yi)
9516 {
9517 int32_t cx = cid % 4;
9518 int32_t cy = cid / 4;
9519 int32_t cc = (cy + yi) * 4 + cx + xi;
9520 int32_t fx = favind % FAVORITECOMBO_PER_ROW;
9521 int32_t fy = favind / FAVORITECOMBO_PER_ROW;
9522 int32_t fc = (fy + yi) * FAVORITECOMBO_PER_ROW + fx + xi + FAVORITECOMBO_PER_PAGE * FavoriteComboPage;
9523
9524 if (cx + xi < 4 && cc < MAXCOMBOS && fx + xi < FAVORITECOMBO_PER_ROW && fy + yi < FAVORITECOMBO_PER_COLUMN)
9525 {
9526 if (favorite_combos[fc] < 0 || force)
9527 {
9528 favorite_combo_modes[fc] = dm_normal;
9529 favorite_combos[fc] = cc;
9530 }
9531 }
9532 }
9533 }
9534 }
9535
9536 void onRCSelectCombo(int32_t c)
9537 {
9538 int32_t drawmap, drawscr;
9539
9540 if(CurrentLayer==0)
9541 {
9542 drawmap=Map.getCurrMap();
9543 drawscr=Map.getCurrScr();
9544 }
9545 else
9546 {
9547 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
9548 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
9549 }
9550 mapscr* draw_mapscr = Map.AbsoluteScr(drawmap, drawscr);
9551 if(!draw_mapscr) return;
9552
9553 Combo=draw_mapscr->data[c];
9554 if(AutoBrush)
9555 BrushWidth = BrushHeight = 1;
9556 }
9557
9558 void onRCScrollToombo(int32_t c)
9559 {
9560 int32_t drawmap, drawscr;
9561
9562 if(CurrentLayer==0)
9563 {
9564 drawmap=Map.getCurrMap();
9565 drawscr=Map.getCurrScr();
9566 }
9567 else
9568 {
9569 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
9570 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
9571 }
9572 mapscr* draw_mapscr = Map.AbsoluteScr(drawmap, drawscr);
9573 if(!draw_mapscr) return;
9574
9575 auto& sqr = combolist[current_combolist];
9576 First[current_combolist]=scrollto_cmb(draw_mapscr->data[c]);
9577 }
9578
9579 enum
9580 {
9581 MENUID_RCSCREEN_PASTE,
9582 MENUID_RCSCREEN_ADVPASTE,
9583 MENUID_RCSCREEN_SPECPASTE,
9584 };
9585
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu rc_menu_screen
9586 60 {
9587
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Copy Screen", onCopy },
9588
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste Screen", &paste_screen_menu, MENUID_RCSCREEN_PASTE },
9589
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "...Advanced Paste", &paste_menu, MENUID_RCSCREEN_ADVPASTE },
9590
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "...Special Paste", &paste_item_menu, MENUID_RCSCREEN_SPECPASTE },
9591 };
9592
9593 void call_options_dlg();
9594 int32_t onOptions()
9595 {
9596 call_options_dlg();
9597 brush_menu.select_uid(MENUID_BRUSH_AUTOBRUSH, AutoBrush);
9598 brush_menu.disable_uid(MENUID_BRUSH_WIDTH, AutoBrush);
9599 brush_menu.disable_uid(MENUID_BRUSH_HEIGHT, AutoBrush);
9600 brush_menu.select_uid(MENUID_BRUSH_FLOATBRUSH, FloatBrush);
9601 brush_menu.select_uid(MENUID_BRUSH_COMBOBRUSH, ComboBrush);
9602 return D_O_K;
9603 }
9604
9605 void follow_twarp(int warpindex)
9606 {
9607 if(warpindex >= 4)
9608 {
9609 InfoDialog("Random Tile Warp",
9610 "This is a random tile warp combo, so it chooses"
9611 " randomly between the screen's four Tile Warps.").show();
9612 warpindex=zc_oldrand()&3;
9613 }
9614
9615 int32_t tm = Map.getCurrMap();
9616 int32_t ts = Map.getCurrScr();
9617 int32_t wt = Map.CurrScr()->tilewarptype[warpindex];
9618
9619 if(wt==wtCAVE || wt==wtNOWARP)
9620 {
9621 char buf[56];
9622 InfoDialog(warptype_string[wt],fmt::format("This screen's Tile Warp {} is set to {}, so it doesn't lead to another screen.",'A'+warpindex,warptype_string[wt]));
9623 return;
9624 }
9625
9626 Map.dowarp(0,warpindex);
9627
9628 if(ts!=Map.getCurrScr() || tm!=Map.getCurrMap())
9629 {
9630 FlashWarpSquare = (TheMaps[tm*MAPSCRS+ts].warpreturnc>>(warpindex*2))&3;
9631 FlashWarpClk = 32;
9632 }
9633 }
9634 void edit_twarp(int warpindex)
9635 {
9636 if(warpindex>=4)
9637 {
9638 InfoDialog("Random Tile Warp",
9639 "This is a random tile warp combo, so it chooses"
9640 " randomly between the screen's four Tile Warps.").show();
9641 warpindex=zc_oldrand()&3;
9642 }
9643
9644 if(warpindex > -1 && warpindex < 4)
9645 onTileWarpIndex(warpindex);
9646 }
9647
9648 int toggle_linked_scrolling()
9649 {
9650 LinkedScroll = LinkedScroll ? 0 : 1;
9651 zc_set_config("zquest","linked_comboscroll",LinkedScroll);
9652 return D_O_K;
9653 }
9654 void on_scroll_cpane()
9655 {
9656 switch (draw_mode)
9657 {
9658 case dm_alias:
9659 combo_alistpos[current_comboalist] = scrollto_alias(combo_apos);
9660 break;
9661 case dm_cpool:
9662 combo_pool_listpos[current_cpoollist] = scrollto_cpool(combo_pool_pos);
9663 break;
9664 case dm_auto:
9665 combo_auto_listpos[current_cautolist] = scrollto_cauto(combo_auto_pos);
9666 break;
9667 default:
9668 First[current_combolist] = scrollto_cmb(Combo);
9669 break;
9670 }
9671 }
9672 void on_edit_cpane()
9673 {
9674 switch (draw_mode)
9675 {
9676 case dm_alias:
9677 onEditComboAlias();
9678 break;
9679 case dm_cpool:
9680 onEditComboPool();
9681 break;
9682 case dm_auto:
9683 onEditAutoCombo();
9684 break;
9685 default:
9686 reset_combo_animations();
9687 reset_combo_animations2();
9688 edit_combo(Combo, true, CSet);
9689 setup_combo_animations();
9690 setup_combo_animations2();
9691 break;
9692 }
9693 }
9694 void open_combo_pages(optional<int> cid)
9695 {
9696 int cmb_id = cid ? *cid : 0;
9697 combo_screen(cmb_id >> 8, cmb_id);
9698 }
9699 void on_cpane_page()
9700 {
9701 switch(draw_mode)
9702 {
9703 case dm_normal:
9704 open_combo_pages(Combo);
9705 break;
9706 case dm_alias:
9707 call_alias_pages(combo_apos);
9708 break;
9709 case dm_auto:
9710 call_autoc_pages(combo_auto_pos);
9711 break;
9712 case dm_cpool:
9713 call_cpool_pages(combo_pool_pos);
9714 break;
9715 }
9716 }
9717 void open_cpane_tilepage()
9718 {
9719 onGotoTiles(combobuf[Combo].o_tile);
9720 }
9721 static int _clicked_fav = 0;
9722 void fav_rc_remove()
9723 {
9724 favorite_combo_modes[_clicked_fav] = dm_normal;
9725 favorite_combos[_clicked_fav] = -1;
9726 mark_save_dirty();
9727 }
9728 void popup_favorites_rc(int f, int x, int y)
9729 {
9730 _clicked_fav = f;
9731 string type;
9732 switch (draw_mode)
9733 {
9734 case dm_alias:
9735 type = "Alias";
9736 break;
9737 case dm_cpool:
9738 type = "Pool";
9739 break;
9740 case dm_auto:
9741 type = "Autocombo";
9742 break;
9743 case dm_normal:
9744 type = "Combo";
9745 break;
9746 default: return;
9747 }
9748 NewMenu rcmenu
9749 {
9750 { fmt::format("Scroll to {}", type), on_scroll_cpane },
9751 { fmt::format("Edit {}", type), on_edit_cpane },
9752 { fmt::format("Open {} Page", type), on_cpane_page },
9753 { fmt::format("Remove Fav {}", type), fav_rc_remove },
9754 };
9755 switch (draw_mode)
9756 {
9757 case dm_normal:
9758 rcmenu.add({
9759 {},
9760 { "Open Tile Page", open_cpane_tilepage },
9761 });
9762 break;
9763 }
9764 rcmenu.pop(x, y);
9765 }
9766 void popup_cpane_rc(int x, int y)
9767 {
9768 string type;
9769 switch (draw_mode)
9770 {
9771 case dm_alias:
9772 type = "Alias";
9773 break;
9774 case dm_cpool:
9775 type = "Pool";
9776 break;
9777 case dm_auto:
9778 type = "Autocombo";
9779 break;
9780 case dm_normal:
9781 type = "Combo";
9782 break;
9783 default: return;
9784 }
9785 NewMenu rcmenu;
9786 switch(draw_mode)
9787 {
9788 case dm_normal:
9789 rcmenu.add({
9790 { fmt::format("Edit {}", type), on_edit_cpane },
9791 { fmt::format("Open {} Page", type), on_cpane_page },
9792 { "Open Tile Page", open_cpane_tilepage },
9793 { "Combo Locations", onComboLocationReport },
9794 {},
9795 { "Scroll to Page...", onGotoPage },
9796 { "Linked Scrolling", toggle_linked_scrolling, nullopt, LinkedScroll ? MFL_SEL : 0 },
9797 });
9798 break;
9799 case dm_alias:
9800 case dm_cpool:
9801 case dm_auto:
9802 rcmenu.add({
9803 { fmt::format("Edit {}", type), on_edit_cpane },
9804 { fmt::format("Open {} Page", type), on_cpane_page },
9805 {},
9806 { "Scroll to Page...", onGotoPage },
9807 { "Linked Scrolling", toggle_linked_scrolling, nullopt, LinkedScroll ? MFL_SEL : 0 },
9808 });
9809 break;
9810 }
9811 rcmenu.pop(x, y);
9812 }
9813
9814 void set_brush_width(int32_t width)
9815 {
9816 BrushWidth = width;
9817 for(int q = 0; q < brush_width_menu.size(); ++q)
9818 brush_width_menu.at(q)->select(q==BrushWidth-1);
9819 refresh(rALL);
9820 }
9821
9822 void set_brush_height(int32_t height)
9823 {
9824 BrushHeight = height;
9825 for(int q = 0; q < brush_height_menu.size(); ++q)
9826 brush_height_menu.at(q)->select(q==BrushHeight-1);
9827 refresh(rALL);
9828 }
9829
9830 1 void restore_mouse()
9831 {
9832 1 ComboBrushPause=1;
9833 1 MouseSprite::set(ZQM_NORMAL);
9834 1 }
9835
9836 static int32_t comboa_cnt=0;
9837 static int32_t combop_cnt=0;
9838 static int32_t layer_cnt=0;
9839
9840 static char paste_ffc_menu_text[21];
9841 static char paste_ffc_menu_text2[21];
9842 static char follow_warp_menu_text[21];
9843 static char follow_warp_menu_text2[21];
9844
9845 static int fake_mouse_b(){return 0;}
9846 static int (*mouseb_proc)();
9847 static bool killed_mouse = false;
9848 void zq_killmouse()
9849 {
9850 if(killed_mouse) return;
9851 mouseb_proc = gui_mouse_b;
9852 gui_mouse_b = fake_mouse_b;
9853 killed_mouse = true;
9854 }
9855 void zq_restoremouse()
9856 {
9857 if(!killed_mouse) return;
9858 gui_mouse_b = mouseb_proc;
9859 killed_mouse = false;
9860 }
9861
9862
9863 void domouse()
9864 {
9865 static int mouse_down = 0;
9866 static int32_t scrolldelay = 0;
9867 auto mousexy = zc_get_mouse();
9868 auto x = mousexy.first;
9869 auto y = mousexy.second;
9870 double startx=mapscreen_x+(showedges?(16*mapscreen_single_scale):0);
9871 double starty=mapscreen_y+(showedges?(16*mapscreen_single_scale):0);
9872 int32_t startxint=mapscreen_x+(showedges?int32_t(16*mapscreen_single_scale):0);
9873 int32_t startyint=mapscreen_y+(showedges?int32_t(16*mapscreen_single_scale):0);
9874 int32_t cx=(x-startx)/(16*mapscreen_single_scale);
9875 int32_t cy=(y-starty)/(16*mapscreen_single_scale);
9876 ComboPosition combo_pos = {cx, cy};
9877
9878 if (draw_mode == dm_auto)
9879 {
9880 if (combo_pos != mouse_combo_pos)
9881 combobrushoverride = get_autocombo_floating_cid(combo_pos, false);
9882 }
9883 else
9884 combobrushoverride = -1;
9885
9886 mouse_combo_pos = combo_pos;
9887 update_combobrush();
9888
9889 ++scrolldelay;
9890
9891 bool x_on_list = false;
9892 for(auto q = 0; q < num_combo_cols; ++q)
9893 {
9894 if((x>=combolist[q].x) && (x<combolist[q].x+(combolist[q].xscale*combolist[q].w)))
9895 {
9896 x_on_list = true;
9897 break;
9898 }
9899 }
9900 if(MouseScroll && x_on_list && (key[KEY_LSHIFT] || key[KEY_RSHIFT] || (scrolldelay&3)==0))
9901 {
9902 int32_t test_list=0;
9903
9904 for(test_list=0; test_list<num_combo_cols; ++test_list)
9905 {
9906 if((x>=combolist[test_list].x) && (x<combolist[test_list].x+(combolist[test_list].xscale*combolist[test_list].w)))
9907 {
9908 break;
9909 }
9910 }
9911
9912 if(test_list<num_combo_cols)
9913 {
9914 if(y>=combolist[test_list].y-mouse_scroll_h && y<=combolist[test_list].y && First[test_list])
9915 {
9916 if((CHECK_CTRL_CMD)&&(key[KEY_ALT] || key[KEY_ALTGR]))
9917 {
9918 First[test_list]=0;
9919 }
9920 else if(CHECK_CTRL_CMD)
9921 {
9922 First[test_list]-=zc_min(First[test_list],256);
9923 }
9924 else if(key[KEY_ALT] || key[KEY_ALTGR])
9925 {
9926 First[test_list]-=zc_min(First[test_list],(combolist[test_list].w*combolist[test_list].h));
9927 }
9928 else
9929 {
9930 First[test_list]-=zc_min(First[test_list],combolist[test_list].w);
9931 }
9932 }
9933
9934 if(y>=combolist[test_list].y+(combolist[test_list].h*combolist[test_list].yscale)-1 && y<combolist[test_list].y+(combolist[test_list].h*combolist[test_list].yscale)+mouse_scroll_h-1 && First[test_list]<(MAXCOMBOS-(combolist[test_list].w*combolist[test_list].h)))
9935 {
9936 int32_t offset = combolist[test_list].w*combolist[test_list].h;
9937
9938 if((CHECK_CTRL_CMD)&&(key[KEY_ALT] || key[KEY_ALTGR]))
9939 {
9940 First[test_list]=MAXCOMBOS-offset;
9941 }
9942 else if(CHECK_CTRL_CMD)
9943 {
9944 First[test_list] = zc_min(MAXCOMBOS-offset, First[test_list]+256);
9945 }
9946 else if(key[KEY_ALT] || key[KEY_ALTGR])
9947 {
9948 First[test_list] = zc_min(MAXCOMBOS-offset, First[test_list]+ offset);
9949 }
9950 else
9951 {
9952 First[test_list] = zc_min(MAXCOMBOS - offset, First[test_list] + combolist[test_list].w);
9953 }
9954 }
9955 }
9956 }
9957
9958 // The screen for this combo_pos, layer 0. Used to access ffcs.
9959 mapscr* scr = Map.Scr(combo_pos);
9960 // The screen for this combo_pos at the CurrentLayer. Could be same as scr.
9961 mapscr* draw_mapscr = scr && CurrentLayer ? Map.Scr(combo_pos, CurrentLayer) : scr;
9962 int c = combo_pos.truncate();
9963 set_active_visible_screen(scr);
9964
9965 //-------------
9966 //tooltip stuff
9967 //-------------
9968 if (active_visible_screen && isinRect(x,y,startxint,startyint,startxint+(256*mapscreen_screenunit_scale)-1,startyint+(176*mapscreen_screenunit_scale)-1))
9969 {
9970 static int mapscr_tooltip_id = ttip_register_id();
9971 bool did_ffttip = false;
9972 int num_ffcs = scr->numFFC();
9973 for(int32_t i=num_ffcs-1; i>=0; i--)
9974 if(scr->ffcs[i].data !=0 && (scr->ffcs[i].layer >= CurrentLayer || (!CurrentLayer && scr->ffcs[i].layer < 0) || (scr->ffcs[i].flags&ffc_overlay)))
9975 {
9976 int32_t ffx = scr->ffcs[i].x.getFloor() + active_visible_screen->dx * 256;
9977 int32_t ffy = scr->ffcs[i].y.getFloor() + active_visible_screen->dy * 176;
9978 int32_t ffw = scr->ffTileWidth(i)*16;
9979 int32_t ffh = scr->ffTileHeight(i)*16;
9980 int32_t cx2 = (x-startxint)/mapscreen_single_scale;
9981 int32_t cy2 = (y-startyint)/mapscreen_single_scale;
9982
9983 if(cx2 >= ffx && cx2 < ffx+ffw && cy2 >= ffy && cy2 < ffy+ffh)
9984 {
9985 // FFC tooltip
9986 if(tooltip_current_ffc != i)
9987 {
9988 clear_tooltip();
9989 }
9990
9991 tooltip_current_ffc = i;
9992 char msg[1024] = {0};
9993 auto& ff = scr->ffcs[i];
9994 sprintf(msg,"FFC: %d Combo: %d\nCSet: %d Type: %s\nScript: %s",
9995 i+1, ff.data,ff.data,
9996 combo_class_buf[combobuf[ff.data].type].name,
9997 (ff.script<=0 ? "(None)" : ffcmap[ff.script-1].scriptname.substr(0,400).c_str()));
9998 ttip_install(mapscr_tooltip_id, msg, startxint+(ffx*mapscreen_single_scale), startyint+(ffy*mapscreen_single_scale), ffw*mapscreen_single_scale, ffh*mapscreen_single_scale, x, y);
9999 did_ffttip = true;
10000 break;
10001 }
10002 }
10003 if(!did_ffttip)
10004 {
10005 if(unsigned(c) < 176 && draw_mapscr && !gui_mouse_b())
10006 {
10007 int cid = draw_mapscr->data[c];
10008 newcombo const& cmb = combobuf[cid];
10009 std::ostringstream oss;
10010 int cs = draw_mapscr->cset[c];
10011 int sflag = draw_mapscr->sflag[c];
10012 oss << "Pos: " << c
10013 << "\nCombo: " << cid
10014 << "\nCSet: " << cs;
10015 if(sflag || cmb.flag)
10016 oss << "\nFlags: " << sflag << ", " << (int)cmb.flag;
10017 if(cmb.type)
10018 oss << "\nCombo type: " << combo_class_buf[cmb.type].name;
10019 if(cmb.label[0])
10020 oss << "\nLabel: " << cmb.label;
10021 ttip_install(mapscr_tooltip_id, oss.str().c_str(), startxint+(cx*16*mapscreen_single_scale), startyint+(cy*16*mapscreen_single_scale), 16*mapscreen_single_scale, 16*mapscreen_single_scale, x, y);
10022 }
10023 }
10024 }
10025
10026 {
10027 size_and_pos* squares[4] = {&itemsqr_pos,&stairsqr_pos,&warparrival_pos,&flagsqr_pos};
10028 for(int32_t j=0; j<4; j++)
10029 {
10030 auto& square = *squares[j];
10031 if(square.rect(x,y))
10032 {
10033 char msg[160];
10034 sprintf(msg,
10035 j==0 ? "Item Location" :
10036 j==1 ? "Stairs Secret\nTriggered when a Trigger Push Block is pushed." :
10037 j==2 ? "Arrival Square\nPlayer's location when they begin/resume the game." :
10038 "Combo Flags");
10039 update_tooltip(x,y,square,msg);
10040 }
10041 }
10042
10043 // Warp Returns
10044 for(int32_t j=0; j<4; j++)
10045 {
10046 size_and_pos& wret = warpret_pos[j];
10047 if(wret.rect(x,y))
10048 {
10049 char msg[160];
10050 sprintf(msg,"Warp Return Square %c\nPlayer's destination after warping to this screen.",(char)('A'+j));
10051 update_tooltip(x,y,wret,msg);
10052 }
10053 }
10054
10055 // Enemies
10056 if(enemy_prev_pos.rect(x,y))
10057 {
10058 char msg[160];
10059 sprintf(msg,"Enemies that appear on this screen.");
10060 update_tooltip(x,y,enemy_prev_pos,msg);
10061 }
10062
10063 int32_t cmd = commands_list.rectind(x,y);
10064 if(cmd > -1)
10065 {
10066 update_tooltip(x,y,commands_list.subsquare(cmd),
10067 fmt::format("Fav Command {}: {}\n{}", cmd,
10068 get_hotkey_name(favorite_commands[cmd]),
10069 get_hotkey_helptext(favorite_commands[cmd])).c_str());
10070 }
10071 }
10072
10073 if(draw_mode==dm_alias)
10074 {
10075 for(int32_t j=0; j<num_combo_cols; ++j)
10076 {
10077 auto& sqr = comboaliaslist[j];
10078 auto ind = sqr.rectind(x,y);
10079 if(ind > -1)
10080 {
10081 auto c2=ind+combo_alistpos[j];
10082 char msg[80];
10083 sprintf(msg, "Combo alias %d", c2);
10084 update_tooltip(x,y,sqr.subsquare(ind), msg);
10085 }
10086 }
10087 }
10088 else if(draw_mode==dm_cpool)
10089 {
10090 for(int32_t j=0; j<num_combo_cols; ++j)
10091 {
10092 auto& sqr = comboaliaslist[j];
10093 auto ind = sqr.rectind(x,y);
10094 if(ind > -1)
10095 {
10096 auto c2=ind+combo_pool_listpos[j];
10097 char msg[80];
10098 sprintf(msg, "Combo Pool %d", c2);
10099 update_tooltip(x,y,sqr.subsquare(ind), msg);
10100 }
10101 }
10102 if(cpool_prev_visible && combopool_prevbtn.rect(x,y))
10103 {
10104 if(do_layer_button_reset(combopool_prevbtn.x,combopool_prevbtn.y,
10105 combopool_prevbtn.w,combopool_prevbtn.h,
10106 weighted_cpool ? "Weighted" : "Unweighted",0,true))
10107 {
10108 weighted_cpool = !weighted_cpool;
10109 }
10110 }
10111 }
10112 else if (draw_mode == dm_auto)
10113 {
10114 for (int32_t j = 0; j < num_combo_cols; ++j)
10115 {
10116 auto& sqr = comboaliaslist[j];
10117 auto ind = sqr.rectind(x, y);
10118 if (ind > -1)
10119 {
10120 auto c2 = ind + combo_auto_listpos[j];
10121 char msg[80];
10122 sprintf(msg, "Auto Combo %d", c2);
10123 update_tooltip(x, y, sqr.subsquare(ind), msg);
10124 }
10125 }
10126 }
10127 else
10128 {
10129 if(combo_preview.rect(x,y))
10130 {
10131 auto str = "Combo Colors:\n"+get_combo_colornames(Combo,CSet);
10132 update_tooltip(x,y,combo_preview,str.c_str());
10133 }
10134 else if(comboprev_buf[0] && combo_preview_text1.rect(x,y))
10135 {
10136 update_tooltip(x,y,combo_preview_text1,comboprev_buf);
10137 }
10138 else if(comboprev_buf2[0] && combo_preview_text2.rect(x,y))
10139 {
10140 update_tooltip(x,y,combo_preview_text2,comboprev_buf2);
10141 }
10142 else for(int32_t j=0; j<num_combo_cols; ++j)
10143 {
10144 auto& sqr = combolist[j];
10145 auto ind = sqr.rectind(x,y);
10146 if(ind > -1)
10147 {
10148 int32_t c2=ind+First[j];
10149 std::ostringstream oss;
10150 newcombo const& cmb = combobuf[c2];
10151 oss << "Combo " << c2 << ": " << combo_class_buf[cmb.type].name;
10152 if(cmb.flag != 0)
10153 oss << "\nInherent flag: " << ZI.getMapFlagName(cmb.flag);
10154 if(!cmb.label.empty())
10155 oss << "\nLabel: " << cmb.label;
10156
10157 update_tooltip(x,y,sqr.subsquare(ind), oss.str().c_str());
10158 }
10159 }
10160 }
10161
10162 if (favorites_list.rect(x, y))
10163 {
10164 int32_t f = favorites_list.rectind(x, y);
10165 int32_t row = f / favorites_list.w;
10166 int32_t col = f % favorites_list.w;
10167 f = (row * FAVORITECOMBO_PER_ROW) + col;
10168
10169 auto& sqr = favorites_list.subsquare(col, row);
10170
10171 char buf[180];
10172 if (favorite_combos[f] == -1)
10173 sprintf(buf, "Fav Combo %d\nEmpty", f);
10174 else
10175 {
10176 switch (favorite_combo_modes[f])
10177 {
10178 case dm_alias:
10179 sprintf(buf, "Fav Combo %d\nAlias %d", f, favorite_combos[f]);
10180 break;
10181 case dm_cpool:
10182 sprintf(buf, "Fav Combo %d\nPool %d", f, favorite_combos[f]);
10183 break;
10184 case dm_auto:
10185 sprintf(buf, "Fav Combo %d\nAutocombo %d", f, favorite_combos[f]);
10186 break;
10187 default:
10188 sprintf(buf, "Fav Combo %d\nCombo %d", f, favorite_combos[f]);
10189 }
10190 }
10191 update_tooltip(x, y, sqr, buf);
10192 }
10193
10194 size_and_pos const& real_mini = zoomed_minimap ? real_minimap_zoomed : real_minimap;
10195 auto ind = real_mini.rectind(x,y);
10196 if(ind > -1)
10197 {
10198 char buf[80];
10199 sprintf(buf,"0x%02X (%d)", ind, ind);
10200 ttip_install(minimap_tooltip_id, buf, real_mini.subsquare(ind), real_mini.x+real_mini.tw(), real_mini.y-16);
10201 ttip_set_highlight_thickness(minimap_tooltip_id, zoomed_minimap ? 2 : 1);
10202 // Make sure always above the other tooltip items to the right of the map (even in big map mode).
10203 ttip_set_z_index(minimap_tooltip_id, 100);
10204 ttip_clear_timer();
10205 }
10206 else
10207 {
10208 ttip_uninstall(minimap_tooltip_id);
10209 }
10210
10211 // Mouse clicking stuff
10212 int real_mb = gui_mouse_b();
10213 int mb = real_mb & ~mouse_down; //Only handle clicks that have not been handled already
10214 auto mz = mouse_z;
10215 bool lclick = mb&1;
10216 bool rclick = mb&2;
10217
10218 FONT* tfont = font;
10219 if(zoomed_minimap)
10220 {
10221 if((lclick||rclick) && !minimap_zoomed.rect(x,y))
10222 {
10223 // 'Clicked off'
10224 mmap_set_zoom(false);
10225 goto domouse_doneclick;
10226 }
10227 }
10228
10229 if(real_mb==0)
10230 {
10231 mouse_down = 0;
10232 canfill=true;
10233 }
10234 else if(lclick || rclick)
10235 {
10236 //on the minimap
10237 if(real_mini.rect(x,y))
10238 {
10239 if(lclick)
10240 select_scr();
10241 else if(rclick && !(mouse_down&2))
10242 {
10243 mmap_set_zoom(!zoomed_minimap);
10244 }
10245 goto domouse_doneclick;
10246 }
10247
10248 if(zoomed_minimap && minimap_zoomed.rect(x,y))
10249 goto domouse_doneclick; //Eat clicks
10250
10251 //on the map tabs
10252 font = get_custom_font(CFONT_GUI);
10253 for(int32_t btn=0; btn<mappage_count; ++btn)
10254 {
10255 if (btn == current_mappage) continue;
10256 char tbuf[15];
10257 sprintf(tbuf, "%d:%02X", map_page[btn].map+1, map_page[btn].screen);
10258 auto& sqr = map_page_bar[btn];
10259 if(sqr.rect(x,y))
10260 {
10261 if(do_layer_button_reset(sqr.x,sqr.y,sqr.w,sqr.h,tbuf,(btn==current_mappage?D_SELECTED:0)))
10262 {
10263 draw_layer_button(screen, sqr.x,sqr.y,sqr.w,sqr.h,tbuf,D_SELECTED);
10264
10265 if (lclick)
10266 {
10267 map_page[current_mappage].map=Map.getCurrMap();
10268 map_page[current_mappage].screen=Map.getCurrScr();
10269 current_mappage=btn;
10270 Map.setCurrMap(map_page[current_mappage].map);
10271 Map.setCurrScr(map_page[current_mappage].screen);
10272 rebuild_trans_table(); //Woo
10273 }
10274 else if (rclick)
10275 {
10276 map_page[btn].map = 0;
10277 map_page[btn].screen = 0;
10278 }
10279 }
10280 goto domouse_doneclick;
10281 }
10282 }
10283
10284 if(compactbtn.rect(x,y))
10285 {
10286 if(do_text_button(compactbtn.x, compactbtn.y, compactbtn.w, compactbtn.h, is_compact ? "< Expand" : "> Compact"));
10287 toggle_is_compact();
10288 goto domouse_doneclick;
10289 }
10290
10291 if(!zoom_in_btn_disabled && zoominbtn.rect(x,y))
10292 {
10293 if(do_text_button(zoominbtn.x, zoominbtn.y, zoominbtn.w, zoominbtn.h, "+"))
10294 change_mapscr_zoom(-1);
10295 goto domouse_doneclick;
10296 }
10297
10298 if(!zoom_out_btn_disabled && zoomoutbtn.rect(x,y))
10299 {
10300 if(do_text_button(zoomoutbtn.x, zoomoutbtn.y, zoomoutbtn.w, zoomoutbtn.h, "-"))
10301 change_mapscr_zoom(1);
10302 goto domouse_doneclick;
10303 }
10304
10305 font = get_zc_font(font_lfont_l);
10306 if(combo_merge_btn.rect(x,y))
10307 {
10308 bool merged = is_compact ? compact_merged_combopane : large_merged_combopane;
10309 if(do_text_button(combo_merge_btn.x,combo_merge_btn.y,combo_merge_btn.w,combo_merge_btn.h,merged ? "<|>" : ">|<"))
10310 {
10311 toggle_merged_mode();
10312 }
10313 goto domouse_doneclick;
10314 }
10315
10316 if(favorites_zoombtn.rect(x,y))
10317 {
10318 bool zoomed = is_compact ? compact_zoomed_fav : large_zoomed_fav;
10319 if(do_text_button(favorites_zoombtn.x,favorites_zoombtn.y,favorites_zoombtn.w,favorites_zoombtn.h,zoomed ? "-" : "+"))
10320 {
10321 toggle_favzoom_mode();
10322 }
10323 goto domouse_doneclick;
10324 }
10325 else if(favorites_x.rect(x,y))
10326 {
10327 if(do_text_button(favorites_x.x,favorites_x.y,favorites_x.w,favorites_x.h,"X"))
10328 {
10329 if (alert_confirm("Clear Favorite Combos", "Are you sure you want"
10330 " to clear all favorite combos?"))
10331 {
10332 for(auto q = 0; q < MAXFAVORITECOMBOS; ++q)
10333 {
10334 favorite_combos[q] = -1;
10335 favorite_combo_modes[q] = dm_normal;
10336 }
10337 mark_save_dirty();
10338 refresh(rFAVORITES);
10339 }
10340 }
10341 goto domouse_doneclick;
10342 }
10343 else if(favorites_infobtn.rect(x,y))
10344 {
10345 if(do_text_button(favorites_infobtn.x,favorites_infobtn.y,favorites_infobtn.w,favorites_infobtn.h,"?"))
10346 {
10347 InfoDialog("Favorite Combos",
10348 "On LClick (empty): Sets clicked favorite to the current combo."
10349 "\nOn LClick: Sets current combo to clicked favorite."
10350 "\nShift+LClick: Sets clicked favorite to current combo."
10351 "\nCtrl+LClick: Clears clicked favorite."
10352 "\nAlt+LClick: Scrolls to clicked favorite."
10353 "\nRClick: Opens context menu."
10354 "\n\nClick the Page buttons (<-/->) to cycle between pages (RClick to jump to a page)"
10355 "\nClick the Zoom button (+/-) to toggle zoom level."
10356 "\nClick the X button to clear all favorite combos.").show();
10357 }
10358 goto domouse_doneclick;
10359 }
10360 else if(favorites_pgleft.rect(x,y))
10361 {
10362 if (do_text_button(favorites_pgleft.x, favorites_pgleft.y, favorites_pgleft.w, favorites_pgleft.h, is_compact ? "<" : "<-"))
10363 {
10364 if (rclick)
10365 {
10366 if(auto val = popup_num_menu(x, y, 1, 9, FavoriteComboPage, [](int p){return fmt::format("Page {}",p);}))
10367 FavoriteComboPage = vbound(*val-1, 0, 8);
10368 }
10369 else
10370 FavoriteComboPage = FavoriteComboPage == 0 ? 8 : --FavoriteComboPage;
10371 reload_zq_gui();
10372 }
10373 goto domouse_doneclick;
10374 }
10375 else if(favorites_pgright.rect(x,y))
10376 {
10377 if (do_text_button(favorites_pgright.x, favorites_pgright.y, favorites_pgright.w, favorites_pgright.h, is_compact ? ">" : "->"))
10378 {
10379 if (rclick)
10380 {
10381 if(auto val = popup_num_menu(x, y, 1, 9, FavoriteComboPage, [](int p){return fmt::format("Page {}",p);}))
10382 FavoriteComboPage = vbound(*val-1, 0, 8);
10383 }
10384 else
10385 FavoriteComboPage = FavoriteComboPage == 8 ? 0 : ++FavoriteComboPage;
10386 reload_zq_gui();
10387 }
10388 goto domouse_doneclick;
10389 }
10390
10391 if(commands_zoombtn.rect(x,y))
10392 {
10393 bool zoomed = is_compact ? compact_zoomed_cmd : large_zoomed_cmd;
10394 if(do_text_button(commands_zoombtn.x,commands_zoombtn.y,commands_zoombtn.w,commands_zoombtn.h,zoomed ? "-" : "+"))
10395 {
10396 toggle_cmdzoom_mode();
10397 }
10398 goto domouse_doneclick;
10399 }
10400 else if(commands_x.rect(x,y))
10401 {
10402 if(do_text_button(commands_x.x,commands_x.y,commands_x.w,commands_x.h,"X"))
10403 {
10404 if (alert_confirm("Clear Favorite Commands", "Are you sure you want"
10405 " to clear all favorite commands?"))
10406 {
10407 for(auto q = 0; q < MAXFAVORITECOMMANDS; ++q)
10408 write_fav_command(q,0);
10409 refresh(rFAVORITES);
10410 }
10411 }
10412 goto domouse_doneclick;
10413 }
10414 else if(commands_infobtn.rect(x,y))
10415 {
10416 if(do_text_button(commands_infobtn.x,commands_infobtn.y,commands_infobtn.w,commands_infobtn.h,"?"))
10417 {
10418 InfoDialog("Favorite Commands",
10419 "On LClick (empty): Choose a favorite command"
10420 "\nOn LClick: Runs the favorite command"
10421 "\nShift+Click: Choose a favorite command"
10422 "\nRClick: Choose a favorite command"
10423 "\nCtrl+Click: Clears clicked command"
10424 "\nAlt+Click: Shows info on the favorite command"
10425 "\n\nClick the Zoom button (+/-) to toggle zoom level"
10426 "\nClick the X button to clear all favorite commands").show();
10427 }
10428 goto domouse_doneclick;
10429 }
10430 font=tfont;
10431
10432 // On the layer panel
10433 font = get_custom_font(CFONT_GUI);
10434 for(int32_t i=0; i<=6; ++i)
10435 {
10436 int32_t spacing_offs = is_compact ? 2 : 10;
10437 int32_t rx = (i * (layerpanel_buttonwidth+spacing_offs+layerpanel_checkbox_wid)) + layer_panel.x+(is_compact?2:6);
10438 int32_t ry = layer_panel.y;
10439
10440 if (i != CurrentLayer && (i == 0 || mapscreen_valid_layers[i - 1]) && isinRect(x,y,rx,ry,rx+layerpanel_buttonwidth-1,ry+layerpanel_buttonheight-1))
10441 {
10442 char tbuf[15];
10443
10444 if (Map.getViewSize() > 1)
10445 {
10446 sprintf(tbuf, "%d", i);
10447 }
10448 else if (i != 0 && mapscreen_valid_layers[i - 1])
10449 {
10450 if (is_compact)
10451 {
10452 sprintf(tbuf, "%s%d %d:%02X",
10453 (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"",
10454 i, Map.CurrScr()->layermap[i-1], Map.CurrScr()->layerscreen[i-1]);
10455 }
10456 else
10457 {
10458 sprintf(tbuf, "%s%d (%d:%02X)",
10459 (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"",
10460 i, Map.CurrScr()->layermap[i-1], Map.CurrScr()->layerscreen[i-1]);
10461 }
10462 }
10463 else
10464 {
10465 sprintf(tbuf, "%d", i);
10466 }
10467
10468 if(do_text_button(rx, ry, layerpanel_buttonwidth, layerpanel_buttonheight, tbuf))
10469 {
10470 CurrentLayer = i;
10471 goto domouse_doneclick;
10472 }
10473 }
10474
10475 auto cbyofs = (layerpanel_buttonheight-layerpanel_checkbox_hei)/2;
10476 if(isinRect(x,y,rx+layerpanel_buttonwidth+1,ry+cbyofs,rx+layerpanel_buttonwidth+1+layerpanel_checkbox_wid-1,ry+2+layerpanel_checkbox_hei-1))
10477 {
10478 do_checkbox(screen,rx+layerpanel_buttonwidth+1,ry+cbyofs,layerpanel_checkbox_wid,layerpanel_checkbox_hei,LayerMaskInt[i]);
10479 goto domouse_doneclick;
10480 }
10481 }
10482 font=tfont;
10483
10484 //Uses lclick/rclick separately
10485
10486 //on the map screen
10487 if(isinRect(x,y,startxint,startyint,startxint+(256*mapscreen_screenunit_scale)-1,startyint+(176*mapscreen_screenunit_scale)-1))
10488 {
10489 if (lclick)
10490 {
10491 Map.setCurrScr(Map.getScreenForPosition(combo_pos));
10492 }
10493
10494 if (draw_mode == dm_auto)
10495 {
10496 if (CHECK_CTRL_CMD)
10497 {
10498 if (canfill)
10499 {
10500 switch (fill_type)
10501 {
10502 case 0:
10503 flood();
10504 break;
10505
10506 case 1:
10507 fill_4();
10508 break;
10509
10510 case 2:
10511 fill_8();
10512 break;
10513
10514 case 3:
10515 fill2_4();
10516 break;
10517
10518 case 4:
10519 fill2_8();
10520 break;
10521 }
10522
10523 canfill = false;
10524 }
10525 }
10526 else
10527 draw(key[KEY_LSHIFT] || key[KEY_RSHIFT]);
10528 }
10529 else if (scr && lclick)
10530 {
10531 int32_t cx2 = (x-startxint)/mapscreen_single_scale;
10532 int32_t cy2 = (y-startyint)/mapscreen_single_scale;
10533
10534 // Move items
10535 if (scr->hasitem && active_visible_screen)
10536 {
10537 int32_t ix = scr->itemx + active_visible_screen->dx * 256;
10538 int32_t iy = scr->itemy + active_visible_screen->dy * 176;
10539
10540 if(cx2 >= ix && cx2 < ix+16 && cy2 >= iy && cy2 < iy+16)
10541 doxypos(scr->itemx, scr->itemy, 11, SNAP_HALF, SNAP_NONE, true, 0, 0, 16, 16);
10542 }
10543
10544 // Move FFCs
10545 int num_ffcs = scr->numFFC();
10546 for(int32_t i=num_ffcs-1; i>=0; i--)
10547 if(scr->ffcs[i].data !=0 && (scr->ffcs[i].layer >= CurrentLayer || (!CurrentLayer && scr->ffcs[i].layer < 0) || (scr->ffcs[i].flags&ffc_overlay)))
10548 {
10549 int32_t ffx = scr->ffcs[i].x.getFloor() + active_visible_screen->dx * 256;
10550 int32_t ffy = scr->ffcs[i].y.getFloor() + active_visible_screen->dy * 176;
10551
10552 if(cx2 >= ffx && cx2 < ffx+(scr->ffTileWidth(i)*16) && cy2 >= ffy && cy2 < ffy+(scr->ffTileHeight(i)*16))
10553 {
10554 moveffc(i, cx2, cy2);
10555 break;
10556 }
10557 }
10558
10559 if(key[KEY_ALT]||key[KEY_ALTGR])
10560 {
10561 if (!draw_mapscr) return;
10562
10563 Combo=draw_mapscr->data[c];
10564 if(AutoBrush)
10565 BrushWidth = BrushHeight = 1;
10566 if(key[KEY_LSHIFT]||key[KEY_RSHIFT])
10567 CSet=draw_mapscr->cset[c];
10568 if(CHECK_CTRL_CMD)
10569 First[current_combolist]=scrollto_cmb(draw_mapscr->data[c]);
10570 }
10571 else if(CHECK_CTRL_CMD)
10572 {
10573 if(canfill)
10574 {
10575 switch(fill_type)
10576 {
10577 case 0:
10578 flood();
10579 break;
10580
10581 case 1:
10582 fill_4();
10583 break;
10584
10585 case 2:
10586 fill_8();
10587 break;
10588
10589 case 3:
10590 fill2_4();
10591 break;
10592
10593 case 4:
10594 fill2_8();
10595 break;
10596 }
10597
10598 canfill=false;
10599 }
10600 }
10601 else draw(key[KEY_LSHIFT] || key[KEY_RSHIFT]);
10602 }
10603 else if (scr && rclick)
10604 {
10605 ComboBrushPause=1;
10606 refresh(rMAP);
10607 restore_mouse();
10608 ComboBrushPause=0;
10609
10610 bool clickedffc = false;
10611
10612 // FFC right-click menu
10613 // This loop also serves to find the free ffc with the smallest slot number.
10614 int num_ffcs = scr->numFFC();
10615 uint32_t earliestfreeffc = num_ffcs;
10616 for(int32_t i=num_ffcs-1; i>=0; i--)
10617 {
10618 auto data = scr->ffcs[i].data;
10619 if(data==0)
10620 {
10621 if(i < earliestfreeffc)
10622 earliestfreeffc = i;
10623 continue;
10624 }
10625
10626 if(clickedffc || !(scr->valid&mVALID))
10627 continue;
10628
10629 if(data!=0 && (scr->ffcs[i].layer >= CurrentLayer || (!CurrentLayer && scr->ffcs[i].layer < 0) || (scr->ffcs[i].flags&ffc_overlay)))
10630 {
10631 int32_t ffx = scr->ffcs[i].x.getFloor() + active_visible_screen->dx * 256;
10632 int32_t ffy = scr->ffcs[i].y.getFloor() + active_visible_screen->dy * 176;
10633 int32_t cx2 = (x-startxint)/mapscreen_single_scale;
10634 int32_t cy2 = (y-startyint)/mapscreen_single_scale;
10635
10636 if(cx2 >= ffx && cx2 < ffx+(scr->ffTileWidth(i)*16) && cy2 >= ffy && cy2 < ffy+(scr->ffTileHeight(i)*16))
10637 {
10638 auto& ffc = scr->ffcs[i];
10639 NewMenu rcmenu
10640 {
10641 { "Copy FFC", [&](){Map.CopyFFC(active_visible_screen->screen, i);} },
10642 { "Paste FFC data", [&]()
10643 {
10644 if(alert_confirm("Confirm Paste", "Really replace the FFC with"
10645 " the data of the copied FFC?"))
10646 {
10647 auto set_ffc_data = Map.getCopyFFCData();
10648 set_ffc_data.x = scr->ffcs[i].x;
10649 set_ffc_data.y = scr->ffcs[i].y;
10650 Map.DoSetFFCCommand(Map.getCurrMap(), active_visible_screen->screen, i, set_ffc_data);
10651 }
10652 }, nullopt, Map.getCopyFFC() < 0 ? MFL_DIS : 0 },
10653 { "Edit FFC", [&](){call_ffc_dialog(i, active_visible_screen->scr, active_visible_screen->screen);} },
10654 { "Clear FFC", [&]()
10655 {
10656 if (alert_confirm("Confirm Clear", "Really clear this Freeform Combo?"))
10657 {
10658 Map.DoSetFFCCommand(Map.getCurrMap(), active_visible_screen->screen, i, {
10659 .x = 0,
10660 .y = 0,
10661 .vx = 0,
10662 .vy = 0,
10663 .ax = 0,
10664 .ay = 0,
10665 .data = 0,
10666 .cset = 0,
10667 .delay = 0,
10668 .link = 0,
10669 .script = 0,
10670 .tw = 1,
10671 .th = 1,
10672 .ew = 16,
10673 .eh = 16,
10674 .flags = ffc_none,
10675 .initd = 0,
10676 });
10677 mark_save_dirty();
10678 }
10679 } },
10680 { "Snap to Grid", [&]()
10681 {
10682 int oldffx = scr->ffcs[i].x.getInt();
10683 int oldffy = scr->ffcs[i].y.getInt();
10684 int pos = COMBOPOS(oldffx,oldffy);
10685 int newffy = COMBOY(pos);
10686 int newffx = COMBOX(pos);
10687
10688 auto set_ffc_data = set_ffc_command::create_data(scr->ffcs[i]);
10689 set_ffc_data.x = newffx;
10690 set_ffc_data.y = newffy;
10691 Map.DoSetFFCCommand(Map.getCurrMap(), active_visible_screen->screen, i, set_ffc_data);
10692
10693 mark_save_dirty();
10694 } },
10695 {},
10696 { "Select Combo", [&]()
10697 {
10698 Combo = ffc.data;
10699 } },
10700 { "Scroll to Combo", [&]()
10701 {
10702 First[current_combolist] = scrollto_cmb(ffc.data);
10703 } },
10704 { "Open Combo Page", [&]()
10705 {
10706 open_combo_pages(ffc.data);
10707 } },
10708 { "Edit Combo", [&]()
10709 {
10710 edit_combo(ffc.data,true,ffc.cset);
10711 } },
10712 };
10713 rcmenu.pop(x, y);
10714 clickedffc = true;
10715 break;
10716 }
10717 }
10718 }
10719
10720 // Combo right-click menu
10721 if(!clickedffc)
10722 {
10723 int warpindex = Map.warpindex(scr->data[c]);
10724 string txt_twarp_follow, txt_twarp_edit, txt_ffc_edit, txt_ffc_paste;
10725 bool show_ffcs = earliestfreeffc < MAXFFCS;
10726 bool dis_paste_ffc = Map.getCopyFFC() < 0;
10727 bool show_warps = warpindex > -1;
10728 bool show_warpback = Map.has_warpback();
10729 // FFC-specific options
10730 if(earliestfreeffc < MAXFFCS)
10731 {
10732 txt_ffc_edit = fmt::format("Edit New FFC {}",earliestfreeffc+1);
10733 if(Map.getCopyFFC()>-1)
10734 txt_ffc_paste = fmt::format("Paste FFC as FFC {}",earliestfreeffc+1);
10735 else
10736 txt_ffc_paste = "Paste FFC";
10737 }
10738
10739 if(warpindex > -1)
10740 {
10741 char letter = warpindex==4 ? 'R' : 'A'+warpindex;
10742 txt_twarp_follow = fmt::format("Follow Tile Warp {}",letter);
10743 txt_twarp_edit = fmt::format("Edit Tile Warp {}",letter);
10744 }
10745
10746 NewMenu draw_rc_menu
10747 {
10748 { "Select Combo", [&]()
10749 {
10750 Combo = draw_mapscr->data[c];
10751 if(AutoBrush)
10752 BrushWidth = BrushHeight = 1;
10753 }, nullopt, !draw_mapscr },
10754 { "Scroll to Combo", [&]()
10755 {
10756 First[current_combolist] = scrollto_cmb(draw_mapscr->data[c]);
10757 }, nullopt, !draw_mapscr },
10758 { "Open Combo Page", [&]()
10759 {
10760 open_combo_pages(draw_mapscr->data[c]);
10761 }, nullopt, !draw_mapscr },
10762 { "Edit Combo", [&]()
10763 {
10764 edit_combo(draw_mapscr->data[c],true,draw_mapscr->cset[c]);
10765 }, nullopt, !draw_mapscr },
10766 {},
10767 { "Replace All", [&](){replace(combo_pos);} },
10768 { "Draw Block", &draw_block_menu },
10769 { "Brush Settings ", &brush_menu },
10770 { "Set Fill Type ", &fill_menu },
10771 };
10772 if(show_warps || show_warpback)
10773 {
10774 draw_rc_menu.add_sep();
10775 if(show_warpback)
10776 draw_rc_menu.add({ "Warp Back", [&](){Map.warpback();} });
10777 if(show_warps)
10778 {
10779 draw_rc_menu.add({ txt_twarp_follow, [&](){follow_twarp(warpindex);} });
10780 draw_rc_menu.add({ txt_twarp_edit, [&](){edit_twarp(warpindex);} });
10781 }
10782 }
10783 if(show_ffcs)
10784 {
10785 draw_rc_menu.add_sep();
10786 draw_rc_menu.add({ txt_ffc_edit, [&]()
10787 {
10788 ffdata tempdat;
10789 // x, y are ints on ffdata (but ffc x, y are zfix), so *10000
10790 tempdat.x = ((int((x-startxint)/mapscreen_single_scale)&(~0x0007)) % 256) * 10000;
10791 tempdat.y = ((int((y-startyint)/mapscreen_single_scale)&(~0x0007)) % 176) * 10000;
10792 tempdat.data = Combo;
10793 tempdat.cset = CSet;
10794 if (SmartFFCPlacement)
10795 {
10796 tempdat.layer = CurrentLayer;
10797 SETFLAG(tempdat.flags, ffc_solid, (combobuf[Combo].walk & 0xF) == 0xF);
10798 }
10799 call_ffc_dialog(earliestfreeffc, tempdat, active_visible_screen->scr, active_visible_screen->screen);
10800 } });
10801 draw_rc_menu.add({ txt_ffc_paste, [&]()
10802 {
10803 auto set_ffc_data = Map.getCopyFFCData();
10804 set_ffc_data.x = ((int((x-startxint)/mapscreen_single_scale)&(~0x0007)) % 256);
10805 set_ffc_data.y = ((int((y-startyint)/mapscreen_single_scale)&(~0x0007)) % 176);
10806 Map.DoSetFFCCommand(Map.getCurrMap(), active_visible_screen->screen, earliestfreeffc, set_ffc_data);
10807 }, nullopt, dis_paste_ffc });
10808 }
10809 draw_rc_menu.add_sep();
10810 draw_rc_menu.add({ "Screen", &rc_menu_screen });
10811 draw_rc_menu.pop(x,y);
10812 }
10813 }
10814 goto domouse_doneclick;
10815 }
10816
10817 //on the drawing mode button
10818 font = get_custom_font(CFONT_GUI);
10819 if(drawmode_btn.rect(x,y))
10820 {
10821 if(lclick)
10822 {
10823 if(do_text_button(drawmode_btn.x,drawmode_btn.y,drawmode_btn.w,drawmode_btn.h,dm_names[draw_mode]))
10824 onDrawingMode();
10825 }
10826 else if(rclick)
10827 drawing_mode_menu.pop(x,y);
10828 goto domouse_doneclick;
10829 }
10830 font=tfont;
10831
10832 //Squares
10833 //
10834 set_active_visible_screen(Map.CurrScr());
10835 {
10836 if(squarepanel_swap_btn.rect(x,y))
10837 {
10838 toggle_compact_sqr_mode();
10839 goto domouse_doneclick;
10840 }
10841 if(squarepanel_up_btn.rect(x,y))
10842 {
10843 cycle_compact_sqr(false);
10844 goto domouse_doneclick;
10845 }
10846 if(squarepanel_down_btn.rect(x,y))
10847 {
10848 cycle_compact_sqr(true);
10849 goto domouse_doneclick;
10850 }
10851
10852 bool do_dummyxy = false;
10853 bool dummymode = key[KEY_LSHIFT] || key[KEY_RSHIFT];
10854
10855 if(itemsqr_pos.rect(x,y))
10856 {
10857 if(dummymode) do_dummyxy = true;
10858 else
10859 {
10860 onItem();
10861
10862 if(!rclick && Map.CurrScr()->hasitem)
10863 doxypos(Map.CurrScr()->itemx,Map.CurrScr()->itemy,11,SNAP_HALF,SNAP_NONE);
10864 goto domouse_doneclick;
10865 }
10866 }
10867
10868 if(stairsqr_pos.rect(x,y))
10869 {
10870 if(dummymode) do_dummyxy = true;
10871 else
10872 {
10873 doxypos(Map.CurrScr()->stairx,Map.CurrScr()->stairy,14,SNAP_WHOLE);
10874 goto domouse_doneclick;
10875 }
10876 }
10877
10878 if(warparrival_pos.rect(x,y))
10879 {
10880 if(dummymode) do_dummyxy = true;
10881 else
10882 {
10883 if(get_qr(qr_NOARRIVALPOINT))
10884 {
10885 info_dsa("Arrival Square",
10886 "The arrival square cannot be used unless the QR 'Use Warp Return "
10887 "Points Only' under 'Quest->Options->Combos' is disabled."
10888 "\nGenerally, this square only exists for compatibility purposes, and is not used"
10889 " in creating new quests.",
10890 "dsa_warparrival");
10891 }
10892 else doxypos(Map.CurrScr()->warparrivalx,Map.CurrScr()->warparrivaly,10,SNAP_HALF,SNAP_NONE);
10893 goto domouse_doneclick;
10894 }
10895 }
10896
10897 if(flagsqr_pos.rect(x,y))
10898 {
10899 if(dummymode) do_dummyxy = true;
10900 else
10901 {
10902 onFlags();
10903 goto domouse_doneclick;
10904 }
10905 }
10906
10907 for(auto q = 0; q < 4; ++q)
10908 {
10909 if(warpret_pos[q].rect(x,y))
10910 {
10911 if(dummymode) do_dummyxy = true;
10912 else
10913 {
10914 doxypos(Map.CurrScr()->warpreturnx[q],Map.CurrScr()->warpreturny[q],9,SNAP_HALF,SNAP_NONE);
10915 goto domouse_doneclick;
10916 }
10917 }
10918 }
10919
10920 if(enemy_prev_pos.rect(x,y))
10921 {
10922 if(dummymode) do_dummyxy = true;
10923 else
10924 {
10925 onEnemies();
10926 goto domouse_doneclick;
10927 }
10928 }
10929
10930 if(do_dummyxy)
10931 {
10932 byte x = 0, y = 0;
10933 showxypos_dummy = true;
10934 doxypos(x,y,13,SNAP_HALF,SNAP_NONE);
10935 goto domouse_doneclick;
10936 }
10937 }
10938
10939 if(draw_mode==dm_alias)
10940 {
10941 for(int32_t j=0; j<num_combo_cols; ++j)
10942 {
10943 if(combolistscrollers[j].rectind(x,y)==0 && !mouse_down)
10944 {
10945 scrollup(j);
10946 goto domouse_doneclick;
10947 }
10948 else if(combolistscrollers[j].rectind(x,y)==1 && !mouse_down)
10949 {
10950 scrolldown(j);
10951 goto domouse_doneclick;
10952 }
10953 else if(comboaliaslist[j].rect(x,y))
10954 {
10955 select_comboa(j);
10956
10957 if(rclick && comboaliaslist[j].rect(gui_mouse_x(),gui_mouse_y()))
10958 popup_cpane_rc(x, y);
10959 goto domouse_doneclick;
10960 }
10961 }
10962 }
10963 else if(draw_mode==dm_cpool)
10964 {
10965 for(int32_t j=0; j<num_combo_cols; ++j)
10966 {
10967 if(combolistscrollers[j].rectind(x,y)==0 && !mouse_down)
10968 {
10969 scrollup(j);
10970 goto domouse_doneclick;
10971 }
10972 else if(combolistscrollers[j].rectind(x,y)==1 && !mouse_down)
10973 {
10974 scrolldown(j);
10975 goto domouse_doneclick;
10976 }
10977 else if(comboaliaslist[j].rect(x,y))
10978 {
10979 select_combop(j);
10980
10981 if(rclick && comboaliaslist[j].rect(gui_mouse_x(),gui_mouse_y()))
10982 popup_cpane_rc(x, y);
10983 goto domouse_doneclick;
10984 }
10985 }
10986 }
10987 else if (draw_mode == dm_auto)
10988 {
10989 for (int32_t j = 0; j < num_combo_cols; ++j)
10990 {
10991 if (combolistscrollers[j].rectind(x, y) == 0 && !mouse_down)
10992 {
10993 scrollup(j);
10994 goto domouse_doneclick;
10995 }
10996 else if (combolistscrollers[j].rectind(x, y) == 1 && !mouse_down)
10997 {
10998 scrolldown(j);
10999 goto domouse_doneclick;
11000 }
11001 else if (comboaliaslist[j].rect(x, y))
11002 {
11003 select_autocombo(j);
11004
11005 if(rclick && comboaliaslist[j].rect(gui_mouse_x(),gui_mouse_y()))
11006 popup_cpane_rc(x, y);
11007 goto domouse_doneclick;
11008 }
11009 }
11010 }
11011 else
11012 {
11013 for(int32_t j=0; j<num_combo_cols; ++j)
11014 {
11015 if(combolistscrollers[j].rectind(x,y)==0 && !mouse_down)
11016 {
11017 scrollup(j);
11018 goto domouse_doneclick;
11019 }
11020 else if(combolistscrollers[j].rectind(x,y)==1 && !mouse_down)
11021 {
11022 scrolldown(j);
11023 goto domouse_doneclick;
11024 }
11025 else if(combolist[j].rect(x,y))
11026 {
11027 select_combo(j);
11028
11029 if(rclick && combolist[j].rect(gui_mouse_x(),gui_mouse_y()))
11030 popup_cpane_rc(x, y);
11031 goto domouse_doneclick;
11032 }
11033 }
11034 }
11035
11036 //on the favorites list
11037 if(favorites_list.rect(x,y))
11038 {
11039 if(lclick)
11040 {
11041 int32_t f=favorites_list.rectind(x,y);
11042 int32_t row=f/favorites_list.w;
11043 int32_t col=f%favorites_list.w;
11044 f = (row*FAVORITECOMBO_PER_ROW)+col;
11045 int32_t fp = f + FAVORITECOMBO_PER_PAGE * FavoriteComboPage;
11046
11047 bool dmcond = favorite_combos[fp] < 0;
11048 if((key[KEY_LSHIFT] || key[KEY_RSHIFT] || dmcond) && !(CHECK_CTRL_CMD))
11049 {
11050 int32_t tempcb=ComboBrush;
11051 ComboBrush=0;
11052
11053 while(gui_mouse_b())
11054 {
11055 x=gui_mouse_x();
11056 y=gui_mouse_y();
11057
11058 switch(draw_mode)
11059 {
11060 case dm_alias:
11061 if (favorite_combos[fp] != combo_apos || favorite_combo_modes[fp] != dm_alias)
11062 {
11063 favorite_combo_modes[fp] = dm_alias;
11064 favorite_combos[fp] = combo_apos;
11065 mark_save_dirty();
11066 }
11067 break;
11068 case dm_cpool:
11069 if (favorite_combos[fp] != combo_pool_pos || favorite_combo_modes[fp] != dm_cpool)
11070 {
11071 favorite_combo_modes[fp] = dm_cpool;
11072 favorite_combos[fp] = combo_pool_pos;
11073 mark_save_dirty();
11074 }
11075 break;
11076 case dm_auto:
11077 if (favorite_combos[fp] != combo_auto_pos || favorite_combo_modes[fp] != dm_auto)
11078 {
11079 favorite_combo_modes[fp] = dm_auto;
11080 favorite_combos[fp] = combo_auto_pos;
11081 mark_save_dirty();
11082 }
11083 break;
11084 default:
11085 if (favorite_combos[fp] != Combo || favorite_combo_modes[fp] != dm_normal)
11086 {
11087 if (BrushWidth > 1 || BrushHeight > 1)
11088 {
11089 add_favorite_combo_block(f, Combo, key[KEY_LSHIFT] || key[KEY_RSHIFT]);
11090 break;
11091 }
11092 favorite_combo_modes[fp] = dm_normal;
11093 favorite_combos[fp] = Combo;
11094 mark_save_dirty();
11095 }
11096 }
11097
11098 custom_vsync();
11099 refresh(rALL | rFAVORITES);
11100 }
11101
11102 ComboBrush=tempcb;
11103 }
11104 else if(CHECK_CTRL_CMD)
11105 {
11106 int32_t tempcb=ComboBrush;
11107 ComboBrush=0;
11108
11109 while(gui_mouse_b())
11110 {
11111 x=gui_mouse_x();
11112 y=gui_mouse_y();
11113
11114 if(favorite_combos[fp]!=-1)
11115 {
11116 favorite_combo_modes[fp] = dm_normal;
11117 favorite_combos[fp]=-1;
11118 mark_save_dirty();
11119 }
11120
11121 custom_vsync();
11122 refresh(rALL | rFAVORITES);
11123 }
11124
11125 ComboBrush=tempcb;
11126 }
11127 else if(key[KEY_ALT] || key[KEY_ALTGR])
11128 {
11129 if(select_favorite())
11130 {
11131 switch(favorite_combo_modes[fp])
11132 {
11133 case dm_alias:
11134 combo_alistpos[current_comboalist]=scrollto_alias(combo_apos);
11135 break;
11136 case dm_cpool:
11137 combo_pool_listpos[current_cpoollist] = scrollto_cpool(combo_pool_pos);
11138 break;
11139 case dm_auto:
11140 combo_auto_listpos[current_cautolist] = scrollto_cauto(combo_auto_pos);
11141 break;
11142 default:
11143 First[current_combolist]=scrollto_cmb(Combo);
11144 }
11145 }
11146 }
11147 else
11148 {
11149 select_favorite();
11150 }
11151 }
11152 else if(rclick)
11153 {
11154 bool valid=select_favorite();
11155
11156 if(valid)
11157 {
11158 int f = favorites_list.rectind(x,y);
11159 int row = f/favorites_list.w;
11160 int col = f%favorites_list.w;
11161 f = (row*FAVORITECOMBO_PER_ROW) + col + (FAVORITECOMBO_PER_PAGE * FavoriteComboPage);
11162 popup_favorites_rc(f, x, y);
11163 }
11164 }
11165 goto domouse_doneclick;
11166 }
11167
11168 //on the commands buttons
11169 int32_t cmd = commands_list.rectind(x,y);
11170 if(cmd > -1)
11171 {
11172 uint hkey = favorite_commands[cmd];
11173 bool shift=(key[KEY_LSHIFT] || key[KEY_RSHIFT]);
11174 bool ctrl=(CHECK_CTRL_CMD);
11175 bool alt=(key[KEY_ALT] || key[KEY_ALTGR]);
11176 bool dis = disabled_hotkey(hkey);
11177 auto& btn = commands_list.subsquare(cmd);
11178 if(!dis||rclick||shift||ctrl||alt)
11179 {
11180 FONT *tfont=font;
11181 font=get_custom_font(CFONT_FAVCMD);
11182 if(do_layer_button_reset(btn.x,btn.y,btn.w,btn.h,
11183 get_hotkey_name(hkey),
11184 selected_hotkey(hkey)?D_SELECTED:0,
11185 true))
11186 {
11187 font=tfont;
11188 if(alt)
11189 {
11190 show_hotkey_info(hkey);
11191 }
11192 else if(ctrl)
11193 {
11194 write_fav_command(cmd,0);
11195 }
11196 else if(rclick || shift || hkey==ZQKEY_NULL_KEY)
11197 {
11198 if(auto newkey = select_fav_command())
11199 write_fav_command(cmd,*newkey);
11200 }
11201 else
11202 {
11203 run_hotkey(hkey);
11204 }
11205 }
11206
11207 font=tfont;
11208 }
11209 goto domouse_doneclick;
11210 }
11211 }
11212
11213 domouse_doneclick:
11214 mouse_down |= mb&3;
11215
11216 if(mouse_z!=0)
11217 {
11218 int32_t z=0;
11219
11220 for(int32_t j=0; j<num_combo_cols; ++j)
11221 {
11222 z=abs(mouse_z);
11223
11224 if(key[KEY_ALT]||key[KEY_ALTGR])
11225 {
11226 z*=combolist[j].h;
11227 }
11228
11229
11230 if(draw_mode == dm_alias)
11231 {
11232 if(comboaliaslist[j].rect(x,y))
11233 {
11234 if(mouse_z<0) //scroll down
11235 {
11236 combo_alistpos[current_comboalist] = zc_min(MAXCOMBOALIASES - comboaliaslist[j].w*comboaliaslist[j].h,
11237 combo_alistpos[current_comboalist]+comboaliaslist[j].w*z);
11238 }
11239 else //scroll up
11240 {
11241 if(combo_alistpos[current_comboalist]>0)
11242 {
11243 combo_alistpos[current_comboalist]-=zc_min(combo_alistpos[current_comboalist],comboaliaslist[j].w*z);
11244 }
11245 }
11246 goto domouse_donez;
11247 }
11248 }
11249 else if(draw_mode == dm_cpool)
11250 {
11251 if(comboaliaslist[j].rect(x,y))
11252 {
11253 if(mouse_z<0) //scroll down
11254 {
11255 combo_pool_listpos[current_cpoollist] = zc_min(MAXCOMBOPOOLS - comboaliaslist[j].w*comboaliaslist[j].h,
11256 combo_pool_listpos[current_cpoollist]+comboaliaslist[j].w*z);
11257 }
11258 else //scroll up
11259 {
11260 if(combo_pool_listpos[current_cpoollist]>0)
11261 {
11262 combo_pool_listpos[current_cpoollist]-=zc_min(combo_pool_listpos[current_cpoollist],comboaliaslist[j].w*z);
11263 }
11264 }
11265 goto domouse_donez;
11266 }
11267 }
11268 else if (draw_mode == dm_auto)
11269 {
11270 if (comboaliaslist[j].rect(x, y))
11271 {
11272 if (mouse_z < 0) //scroll down
11273 {
11274 combo_auto_listpos[current_cautolist] = zc_min(MAXAUTOCOMBOS - comboaliaslist[j].w * comboaliaslist[j].h,
11275 combo_auto_listpos[current_cautolist] + comboaliaslist[j].w * z);
11276 }
11277 else //scroll up
11278 {
11279 if (combo_auto_listpos[current_cautolist] > 0)
11280 {
11281 combo_auto_listpos[current_cautolist] -= zc_min(combo_auto_listpos[current_cautolist], comboaliaslist[j].w * z);
11282 }
11283 }
11284 goto domouse_donez;
11285 }
11286 }
11287 else
11288 {
11289 if(combolist[j].rect(x,y))
11290 {
11291 if(mouse_z<0) //scroll down
11292 {
11293 First[current_combolist] = zc_min(MAXCOMBOS-combolist[j].w*combolist[j].h,
11294 First[current_combolist] + combolist[j].w*z);
11295 }
11296 else //scroll up
11297 {
11298 if(First[current_combolist]>0)
11299 {
11300 First[current_combolist]-=zc_min(First[current_combolist],combolist[j].w*z);
11301 }
11302 }
11303 goto domouse_donez;
11304 }
11305 }
11306 }
11307
11308 z=abs(mouse_z);
11309
11310 if(real_mini.rect(x,y))
11311 {
11312 for(int32_t i=0; i<z; ++i)
11313 {
11314 if(mouse_z>0) onIncMap();
11315 else onDecMap();
11316 }
11317 goto domouse_donez;
11318 }
11319
11320 if(is_compact && compact_square_panels
11321 && squares_panel.rect(x,y))
11322 {
11323 cycle_compact_sqr(mouse_z < 0);
11324 goto domouse_donez;
11325 }
11326 domouse_donez:
11327 position_mouse_z(0);
11328 }
11329
11330 // Mouse buttons.
11331 {
11332 ALLEGRO_MOUSE_STATE state;
11333 al_get_mouse_state(&state);
11334
11335 static bool btn_4_was_down;
11336 static bool btn_5_was_down;
11337
11338 bool btn_4_down = al_mouse_button_down(&state, 4);
11339 bool btn_5_down = al_mouse_button_down(&state, 5);
11340
11341 if (btn_4_was_down && !btn_4_down)
11342 Map.GoBack();
11343 else if (btn_5_was_down && !btn_5_down)
11344 Map.GoForward();
11345
11346 btn_4_was_down = btn_4_down;
11347 btn_5_was_down = btn_5_down;
11348 }
11349
11350 font = tfont;
11351 active_visible_screen = nullptr;
11352 }
11353
11354 int32_t d_viewpal_proc(int32_t msg, DIALOG *d, int32_t c)
11355 {
11356 int32_t ret = d_bitmap_proc(msg, d, c);
11357 char* buf = (char*)d->dp2; //buffer to store the color code in
11358 DIALOG* d2 = (DIALOG*)d->dp3; //DIALOG* to update the text proc
11359 if(!buf)
11360 return ret;
11361 switch(msg)
11362 {
11363 case MSG_IDLE:
11364 case MSG_GOTMOUSE:
11365 case MSG_LOSTMOUSE:
11366 break;
11367 default:
11368 return ret;
11369 }
11370 char t[16];
11371 memcpy(t, buf, 16);
11372 int32_t x = gui_mouse_x() - d->x;
11373 int32_t y = gui_mouse_y() - d->y;
11374 if(msg != MSG_LOSTMOUSE && isinRect(x, y, 0, 0, d->w-1, d->h-1))
11375 {
11376 float palscale = 1.5;
11377 for(int32_t i = 0; i<256; ++i)
11378 if(isinRect(x,y,(int32_t)(((i&31)<<3)*palscale),(int32_t)(((i&0xE0)>>2)*palscale), (int32_t)((((i&31)<<3)+7)*palscale),(int32_t)((((i&0xE0)>>2)+7)*palscale)))
11379 {
11380 sprintf(buf, "0x%02X (%03d) ", i, i); //Extra spaces to increase drawn width, so it draws the blank area
11381 break;
11382 }
11383 }
11384 else memset(buf, ' ', 15);
11385 if(strcmp(buf, t) && d2 && d2->proc == jwin_text_proc && d2->dp == d->dp2)
11386 object_message(d2, MSG_DRAW, 0);
11387 return ret;
11388 }
11389
11390 static DIALOG showpal_dlg[] =
11391 {
11392 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
11393 { jwin_win_proc, 24, 68, 272, 119, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "View Palette", NULL, NULL },
11394 { jwin_frame_proc, 30, 76+16, 260, 68, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
11395 { d_viewpal_proc, 32, 76+18, 256, 64, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11396 { jwin_text_proc, 32+8,76+18+66, 20, 8, vc(11), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
11397 { jwin_button_proc, 130, 144+18, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
11398 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11399 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
11400 };
11401
11402 int32_t onShowPal()
11403 {
11404 float palscale = 1.5;
11405
11406 BITMAP *palbmp = create_bitmap_ex(8,(int32_t)(256*palscale),(int32_t)(64*palscale));
11407
11408 if(!palbmp)
11409 return D_O_K;
11410 clear_to_color(palbmp,jwin_pal[jcBOX]); //If not cleared, random static appears between swatches! -E
11411 showpal_dlg[0].dp2=get_zc_font(font_lfont);
11412
11413 for(int32_t i=0; i<256; i++)
11414 rectfill(palbmp,(int32_t)(((i&31)<<3)*palscale),(int32_t)(((i&0xE0)>>2)*palscale), (int32_t)((((i&31)<<3)+7)*palscale),(int32_t)((((i&0xE0)>>2)+7)*palscale),i);
11415 showpal_dlg[2].dp=(void *)palbmp;
11416 char buf[16] = {0};
11417 showpal_dlg[2].dp2=(void *)buf;
11418 showpal_dlg[2].dp3=(void *)&(showpal_dlg[3]);
11419 showpal_dlg[3].dp=(void *)buf;
11420 showpal_dlg[3].dp2=(void *)get_zc_font(font_deffont);
11421
11422 large_dialog(showpal_dlg);
11423 do_zqdialog(showpal_dlg,2);
11424 destroy_bitmap(palbmp);
11425 return D_O_K;
11426 }
11427
11428 static DIALOG csetfix_dlg[] =
11429 {
11430 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
11431 { jwin_win_proc, 72, 80, 176+1, 96+1, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "CSet Fix", NULL, NULL },
11432 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11433 { jwin_radio_proc, 104+22, 108, 80+1, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "Full Screen", NULL, NULL },
11434 { jwin_radio_proc, 104+22, 118+2, 80+1, 8+1, vc(14), vc(1), 0, D_SELECTED, 0, 0, (void *) "Dungeon Floor", NULL, NULL },
11435 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
11436 { jwin_check_proc, 104+22, 128+4, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, (void *) "All Layers", NULL, NULL },
11437 { jwin_button_proc, 90, 152, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
11438 { jwin_button_proc, 170, 152, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
11439 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
11440 };
11441
11442 int32_t onCSetFix()
11443 {
11444 restore_mouse();
11445 csetfix_dlg[0].dp2=get_zc_font(font_lfont);
11446 int32_t s=2,x2=14,y2=9;
11447
11448 large_dialog(csetfix_dlg);
11449
11450 if(do_zqdialog(csetfix_dlg,-1)==6)
11451 {
11452 if(csetfix_dlg[2].flags&D_SELECTED)
11453 {
11454 s=0;
11455 x2=16;
11456 y2=11;
11457 }
11458
11459 if(csetfix_dlg[5].flags&D_SELECTED)
11460 {
11461 /*
11462 int32_t drawmap, drawscr;
11463 if (CurrentLayer==0)
11464 {
11465 drawmap=Map.getCurrMap();
11466 drawscr=Map.getCurrScr();
11467 }
11468 else
11469 {
11470 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
11471 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
11472 }
11473 mapscr* draw_mapscr = Map.AbsoluteScr(drawmap, drawscr);
11474 if(!draw_mapscr) return;
11475 mark_save_dirty();
11476 Map.Ugo();
11477
11478 if(!(draw_mapscr->valid&mVALID))
11479 {
11480 Map.CurrScr()->valid|=mVALID;
11481 draw_mapscr->valid|=mVALID;
11482 Map.setcolor(Color);
11483 }
11484 for(int32_t i=0; i<176; i++)
11485 {
11486 draw_mapscr->data[i]=Combo;
11487 draw_mapscr->cset[i]=CSet;
11488 }
11489 refresh(rMAP+rSCRMAP);
11490 */
11491 }
11492
11493 Map.StartListCommand();
11494 for(int32_t y=s; y<y2; y++)
11495 {
11496 for(int32_t x=s; x<x2; x++)
11497 {
11498 Map.DoSetComboCommand(Map.getCurrMap(), Map.getCurrScr(), (y<<4)+x, -1, CSet);
11499 }
11500 }
11501 Map.FinishListCommand();
11502
11503 refresh(rMAP);
11504 mark_save_dirty();
11505 }
11506
11507 return D_O_K;
11508 }
11509 static bool doAllSolidWater()
11510 {
11511 for(int32_t i=0; i < MAXCOMBOS; ++i)
11512 {
11513 if(combo_class_buf[combobuf[i].type].water!=0)
11514 {
11515 combobuf[i].walk |= 0x0F; //Solid
11516 }
11517 }
11518 return true;
11519 }
11520 static bool doNoSolidWater()
11521 {
11522 for(int32_t i=0; i < MAXCOMBOS; ++i)
11523 {
11524 if(combo_class_buf[combobuf[i].type].water!=0)
11525 {
11526 combobuf[i].walk &= ~0x0F; //Non-solid
11527 }
11528 }
11529 return true;
11530 }
11531 int32_t onWaterSolidity()
11532 {
11533 AlertFuncDialog("Water Conversion",
11534 "Forcibly set the solidity of all 'Liquid' combos in the quest?",
11535 ""
11536 ).add_buttons(2,
11537 { "Solid", "Non-Solid", "Cancel" },
11538 { doAllSolidWater, doNoSolidWater, nullptr }
11539 ).show();
11540 return D_O_K;
11541 }
11542
11543 static bool doAllEffectSquare()
11544 {
11545 for(int32_t i=0; i < MAXCOMBOS; ++i)
11546 {
11547 combobuf[i].walk |= 0xF0; //Effect
11548 }
11549 return true;
11550 }
11551 static bool doBlankEffectSquare()
11552 {
11553 for(int32_t i=0; i < MAXCOMBOS; ++i)
11554 {
11555 if(combobuf[i].is_blank(true))
11556 {
11557 combobuf[i].walk |= 0xF0; //Effect
11558 }
11559 }
11560 return true;
11561 }
11562
11563 int32_t onEffectFix()
11564 {
11565 AlertFuncDialog("Effect Square Conversion",
11566 "Forcibly fill the green effect square of all combos in the quest?",
11567 ""
11568 ).add_buttons(2,
11569 { "All", "Blank Only", "Cancel" },
11570 { doAllEffectSquare, doBlankEffectSquare, nullptr }
11571 ).show();
11572 return D_O_K;
11573 }
11574
11575 static bool clear_green_arrival_squares()
11576 {
11577 for(mapscr& scr : TheMaps)
11578 {
11579 if(!scr.valid) continue;
11580 scr.warparrivalx = 0;
11581 scr.warparrivaly = 0;
11582 }
11583 set_qr(qr_NOARRIVALPOINT, true);
11584 return true;
11585 }
11586
11587 static bool replace_green_arrival_squares()
11588 {
11589 // Check for conflicts first
11590 bool has_conflicts = false;
11591
11592 for(mapscr& scr : TheMaps)
11593 {
11594 if(!scr.valid) continue;
11595 if(!(scr.warparrivalx || scr.warparrivaly)) continue;
11596 if(scr.warpreturnx[0] || scr.warpreturny[0])
11597 {
11598 has_conflicts = true;
11599 break;
11600 }
11601 }
11602
11603 enum
11604 {
11605 NOT_ASKED = -1,
11606 MODE_FORCE, MODE_IGNORE, MODE_FIND_IGNORE, MODE_FIND_FORCE, MODE_CANCEL
11607 };
11608 int mode = NOT_ASKED;
11609
11610 if(has_conflicts)
11611 {
11612 AlertFuncDialog("Handle Conflicts",
11613 "Warp Square A is not available for all screens that have arrival squares."
11614 " How should this be handled? (See '?' for more info)",
11615 "Overwrite A: Replace the existing warp return square A with the position of the green arrival square"
11616 "\nIgnore: Do nothing if warp return square A exists"
11617 "\nFind Space or Ignore: Choose another, unused, square to set to the position of the green arrival square."
11618 " If none are unused, 'Ignore' instead."
11619 "\nFind Space or Overwrite: Choose another, unused square to set to the position of the green arrival square."
11620 " If none are unused, 'Overwrite A' instead."
11621 "\nCancel: Don't do anything"
11622 ).add_buttons(1,
11623 { "Overwrite A", "Ignore", "Find Space or Ignore", "Find Space or Overwrite A", "Cancel" },
11624 mode
11625 ).show();
11626 if(mode == NOT_ASKED || mode == MODE_CANCEL)
11627 return false;
11628 }
11629 for(mapscr& scr : TheMaps)
11630 {
11631 if(!scr.valid) continue;
11632 if(!(scr.warparrivalx || scr.warparrivaly)) continue;
11633 int indx = 0;
11634 if(scr.warpreturnx[0] || scr.warpreturny[0])
11635 {
11636 if(mode == MODE_IGNORE) continue; // Warp A not free, so ignore
11637 if(mode != MODE_FORCE)
11638 {
11639 for(int q = 1; q < 4; ++q)
11640 {
11641 if(scr.warpreturnx[q] || scr.warpreturny[q])
11642 continue;
11643 indx = q; // Use this warp, since it's free
11644 break;
11645 }
11646 if(indx == 0 && mode == MODE_FIND_IGNORE)
11647 continue; // Nothing free, so ignore
11648 }
11649 }
11650 scr.warpreturnx[indx] = scr.warparrivalx;
11651 scr.warpreturny[indx] = scr.warparrivaly;
11652 scr.warparrivalx = 0;
11653 scr.warparrivaly = 0;
11654 }
11655 set_qr(qr_NOARRIVALPOINT, true);
11656 return true;
11657 }
11658
11659 int32_t onRemoveOldArrivalSquare()
11660 {
11661 AlertFuncDialog("Arrival Square Removal",
11662 "Clear the old green 'Arrival' squares for the whole quest?"
11663 "\n(There will be no further confirmation, and this operation cannot be undone)",
11664 ""
11665 ).add_buttons(2,
11666 { "Replace With Blue Return Square", "Clear Completely", "Cancel" },
11667 { replace_green_arrival_squares, clear_green_arrival_squares, nullptr }
11668 ).show();
11669 return D_O_K;
11670 }
11671
11672 byte* getPalPointer(int32_t pal, int32_t cset)
11673 {
11674 if (pal < 0) return colordata + CSET(cset)*3;
11675 byte* ret = colordata + CSET(pal*pdLEVEL+poLEVEL)*3;
11676 switch(cset)
11677 {
11678 case 2: case 3: case 4:
11679 return ret + CSET(cset-2)*3;
11680 case 9:
11681 return ret + CSET(3)*3;
11682 case 1:
11683 return ret + CSET(13)*3;
11684 case 5:
11685 return ret + CSET(14)*3;
11686 case 7:
11687 return ret + CSET(15)*3;
11688 case 8:
11689 return ret + CSET(16)*3;
11690 }
11691 return NULL;
11692 }
11693
11694 void copyCSet(int32_t destpal, int32_t destcset, int32_t srcpal, int32_t srccset)
11695 {
11696 byte* dest = getPalPointer(destpal, destcset);
11697 byte* src = getPalPointer(srcpal, srccset);
11698 if (dest && src)
11699 {
11700 memcpy(dest, src, 16*3);
11701 }
11702 }
11703
11704 void setColorPalette(int32_t flags, int32_t lowpal, int32_t highpal)
11705 {
11706 for (auto q = lowpal; q <= highpal; ++q)
11707 {
11708 for (auto c = 0; c < 12; ++c)
11709 {
11710 if (!(flags&(1<<c))) continue;
11711 copyCSet(q, c, -1, c);
11712 }
11713 }
11714 }
11715
11716 void setPitDamage(int32_t flags, int32_t lowcombo, int32_t highcombo, int32_t damage)
11717 {
11718 for(int32_t i=lowcombo; i < highcombo; ++i)
11719 {
11720 if((combobuf[i].type == cPITFALL && (flags & (1<<0)))
11721 || (combobuf[i].type == cWATER && !(combobuf[i].usrflags & (1<<0)) && (flags & (1<<1)))
11722 || (combobuf[i].type == cWATER && (combobuf[i].usrflags & (1<<0)) && (flags & (1<<2))))
11723 {
11724 if ((combobuf[i].type != cPITFALL || (flags & (1<<9)) || !(combobuf[i].usrflags & (1<<0)))
11725 && ((flags & (1<<8)) || combobuf[i].c_attributes[0] == 0))
11726 combobuf[i].c_attributes[0] = damage;
11727 }
11728 }
11729 }
11730
11731 static DIALOG template_dlg[] =
11732 {
11733 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
11734 { jwin_win_proc, 72, 80, 176+1, 116+1, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "NES Dungeon Template", NULL, NULL },
11735 { d_comboframe_proc, 178, 122+3, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
11736 { d_combo_proc, 180, 124+3, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11737 // { d_bitmap_proc, 180, 104, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11738 { jwin_radio_proc, 104+33, 128+3, 64+1, 8+1, vc(14), vc(1), 0, D_SELECTED, 0, 0, (void *) "Floor:", NULL, NULL },
11739 { jwin_radio_proc, 104+33, 148+3, 64+1, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "No Floor", NULL, NULL },
11740 { jwin_button_proc, 90, 172, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
11741 { jwin_button_proc, 170, 172, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
11742 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11743 { jwin_text_proc, 104, 102, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "This copies the contents of", NULL, NULL },
11744 { jwin_text_proc, 104, 112, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "screen 83 of the current map.", NULL, NULL },
11745 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
11746 };
11747
11748 int32_t onTemplate()
11749 {
11750 static bool donethis=false;
11751
11752 if(!donethis||!(key[KEY_LSHIFT]||key[KEY_RSHIFT]))
11753 {
11754 template_dlg[2].d1=Combo;
11755 template_dlg[2].fg=CSet;
11756 donethis=true;
11757 }
11758
11759 restore_mouse();
11760
11761 if(Map.getCurrScr()==TEMPLATE)
11762 return D_O_K;
11763
11764 // BITMAP *floor_bmp = create_bitmap_ex(8,16,16);
11765 // if(!floor_bmp) return D_O_K;
11766 template_dlg[0].dp2=get_zc_font(font_lfont);
11767 // put_combo(floor_bmp,0,0,Combo,CSet,0,0);
11768 // template_dlg[2].dp=floor_bmp;
11769
11770 large_dialog(template_dlg);
11771
11772 if(do_zqdialog(template_dlg,-1)==5)
11773 {
11774 mark_save_dirty();
11775 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
11776 Map.DoTemplateCommand((template_dlg[3].flags==D_SELECTED) ? template_dlg[2].d1 : -1, template_dlg[2].fg, screen);
11777 refresh(rMAP+rSCRMAP);
11778 }
11779
11780 // destroy_bitmap(floor_bmp);
11781 return D_O_K;
11782 }
11783
11784 static DIALOG cflag_dlg[] =
11785 {
11786 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
11787 12 { jwin_win_proc, 60-12, 40, 200+24, 148, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
11788 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11789 12 { jwin_abclist_proc, 72-12-4, 60+4, 176+24+8, 92+3, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, NULL, NULL, NULL },
11790 12 { jwin_button_proc, 70, 163, 51, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
11791 12 { jwin_button_proc, 190, 163, 51, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
11792 12 { jwin_button_proc, 130, 163, 51, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Help", NULL, NULL },
11793 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
11794 };
11795
11796
11797 void questrev_help()
11798 {
11799 displayinfo("Help","The revision number of your quest.");
11800 }
11801
11802 void questminrev_help()
11803 {
11804 displayinfo("Help","If a player's saved game was from a revision less than the minimum revision, they have to restart from the beginning. This is useful if you make major changes to your quest.");
11805 }
11806
11807 int32_t select_cflag(const char *prompt,int32_t flag)
11808 {
11809 cflag_dlg[0].dp=(void *)prompt;
11810 cflag_dlg[0].dp2=get_zc_font(font_lfont);
11811 GUI::ListData ld = GUI::ZCListData::mapflag(numericalFlags, true);
11812 ListData select_cflag_list = ld.getJWin(&font);
11813 auto index = ld.findIndex(flag);
11814 cflag_dlg[2].d1=index.value_or(0);
11815 cflag_dlg[2].dp=(void *) &select_cflag_list;
11816
11817 large_dialog(cflag_dlg);
11818
11819 int32_t ret;
11820
11821 do
11822 {
11823 ret=do_zqdialog(cflag_dlg,2);
11824
11825 if(ret==5)
11826 {
11827 cflag_help(ld.getValue(cflag_dlg[2].d1));
11828 }
11829 }
11830 while(ret==5);
11831
11832 if(ret==0||ret==4)
11833 {
11834 position_mouse_z(0);
11835 return -1;
11836 }
11837
11838 return ld.getValue(cflag_dlg[2].d1);
11839 }
11840
11841 int32_t select_flag(int32_t &f)
11842 {
11843 int32_t ret=select_cflag("Flag Type",f);
11844
11845 if(ret>=0)
11846 {
11847 f=ret;
11848 return true;
11849 }
11850
11851 return false;
11852 }
11853
11854 int32_t d_scombo_proc(int32_t msg,DIALOG *d,int32_t c)
11855 {
11856 //these are here to bypass compiler warnings about unused arguments
11857 c=c;
11858
11859 switch(msg)
11860 {
11861 case MSG_CLICK:
11862 {
11863 int32_t c2=d->d1;
11864 int32_t cs=d->fg;
11865 int32_t f=d->d2;
11866
11867 if(d->bg==1 || (CHECK_CTRL_CMD))
11868 {
11869 while(gui_mouse_b())
11870 {
11871 /* do nothing */
11872 rest(1);
11873 }
11874
11875 if(select_flag(f))
11876 {
11877 d->d2=f;
11878
11879 }
11880 }
11881 else if(key[KEY_LSHIFT])
11882 {
11883 if(gui_mouse_b()&1)
11884 {
11885 d->d1++;
11886
11887 if(d->d1>=MAXCOMBOS) d->d1=0;
11888 }
11889 else if(gui_mouse_b()&2)
11890 {
11891 d->d1--;
11892
11893 if(d->d1<0) d->d1=MAXCOMBOS-1;
11894 }
11895 }
11896 else if(key[KEY_RSHIFT])
11897 {
11898 if(gui_mouse_b()&1)
11899 {
11900 d->fg++;
11901
11902 if(d->fg>11) d->fg=0;
11903 }
11904 else if(gui_mouse_b()&2)
11905 {
11906 d->fg--;
11907
11908 if(d->fg<0) d->fg=11;
11909 }
11910 }
11911 else if(key[KEY_ALT])
11912 {
11913 if(gui_mouse_b()&1)
11914 {
11915 d->d1 = Combo;
11916 d->fg = CSet;
11917 }
11918 }
11919 else
11920 {
11921 if(select_combo_2(c2, cs))
11922 {
11923 d->d1=c2;
11924 d->fg=cs;
11925 }
11926 }
11927
11928 return D_REDRAW;
11929 }
11930 break;
11931
11932 case MSG_DRAW:
11933 d->w = 32;
11934 d->h = 32;
11935
11936 BITMAP *buf = create_bitmap_ex(8,16,16);
11937 BITMAP *bigbmp = create_bitmap_ex(8,d->w,d->h);
11938
11939 if(buf && bigbmp)
11940 {
11941 clear_bitmap(buf);
11942
11943 if(d->bg) //flags only
11944 {
11945 put_flag(buf,0,0,d->d2);
11946 }
11947 else if(d->d1)
11948 {
11949 putcombo(buf,0,0,d->d1,d->fg);
11950
11951 if(Flags&cFLAGS)
11952 put_flags(buf,0,0,d->d1,d->fg,cFLAGS,d->d2);
11953 }
11954
11955 stretch_blit(buf, bigbmp, 0,0, 16, 16, 0, 0, d->w, d->h);
11956 destroy_bitmap(buf);
11957 blit(bigbmp,screen,0,0,d->x-1,d->y-1,d->w,d->h);
11958 destroy_bitmap(bigbmp);
11959 }
11960
11961
11962 /*BITMAP *buf = create_bitmap_ex(8,16,16);
11963 if(buf)
11964 {
11965 clear_bitmap(buf);
11966 if(d->d1)
11967 putcombo(buf,0,0,d->d1,d->fg);
11968
11969 blit(buf,screen,0,0,d->x,d->y,d->w,d->h);
11970 destroy_bitmap(buf);
11971 }*/
11972 break;
11973 }
11974
11975 return D_O_K;
11976 }
11977
11978 int32_t onSecretF();
11979
11980 static int32_t secret_burn_list[] =
11981 {
11982 // dialog control number
11983 4, 5, 6, 7, 48, 49, 50, 51, 92, 93, 94, 95, -1
11984 };
11985
11986 static int32_t secret_arrow_list[] =
11987 {
11988 // dialog control number
11989 8, 9, 10, 52, 53, 54, 96, 97, 98, -1
11990 };
11991
11992 static int32_t secret_bomb_list[] =
11993 {
11994 // dialog control number
11995 11, 12, 55, 56, 99, 100, -1
11996 };
11997
11998 static int32_t secret_boomerang_list[] =
11999 {
12000 // dialog control number
12001 13, 14, 15, 57, 58, 59, 101, 102, 103, -1
12002 };
12003
12004 static int32_t secret_magic_list[] =
12005 {
12006 // dialog control number
12007 16, 17, 60, 61, 104, 105, -1
12008 };
12009
12010 static int32_t secret_sword_list[] =
12011 {
12012 // dialog control number
12013 18, 19, 20, 21, 22, 23, 24, 25, 62, 63, 64, 65, 66, 67, 68, 69, 106, 107, 108, 109, 110, 111, 112, 113, -1
12014 };
12015
12016 static int32_t secret_misc_list[] =
12017 {
12018 // dialog control number
12019 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, -1
12020 };
12021
12022 static TABPANEL secret_tabs[] =
12023 {
12024 // (text)
12025 { (char *)"Burn", D_SELECTED, secret_burn_list, 0, NULL },
12026 { (char *)"Arrow", 0, secret_arrow_list, 0, NULL },
12027 { (char *)"Bomb", 0, secret_bomb_list, 0, NULL },
12028 { (char *)"Boomerang", 0, secret_boomerang_list, 0, NULL },
12029 { (char *)"Magic", 0, secret_magic_list, 0, NULL },
12030 { (char *)"Sword", 0, secret_sword_list, 0, NULL },
12031 { (char *)"Misc", 0, secret_misc_list, 0, NULL },
12032 { NULL, 0, NULL, 0, NULL }
12033 };
12034
12035 static DIALOG secret_dlg[] =
12036 {
12037 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3)
12038 { jwin_win_proc, 0, 0, 301, 212, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
12039 { jwin_tab_proc, 6, 25, 289, 156, 0, 0, 0, 0, 0, 0, (void *) secret_tabs, NULL, (void *)secret_dlg },
12040 { jwin_button_proc, 80, 187, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
12041 { jwin_button_proc, 160, 187, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
12042 // 4
12043 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Any Fire", NULL, NULL },
12044 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Strong Fire", NULL, NULL },
12045 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Magic Fire", NULL, NULL },
12046 { jwin_text_proc, 12, 119, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Divine Fire", NULL, NULL },
12047 //8
12048 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Wooden Arrow", NULL, NULL },
12049 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Silver Arrow", NULL, NULL },
12050 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Golden Arrow", NULL, NULL },
12051 //11
12052 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Bomb", NULL, NULL },
12053 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Super Bomb", NULL, NULL },
12054 //13
12055 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Wooden Boomerang", NULL, NULL },
12056 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Magic Boomerang", NULL, NULL },
12057 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Fire Boomerang", NULL, NULL },
12058 //16
12059 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Wand Magic", NULL, NULL },
12060 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Reflected Magic", NULL, NULL },
12061 //18
12062 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Sword", NULL, NULL },
12063 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "White Sword", NULL, NULL },
12064 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Magic Sword", NULL, NULL },
12065 { jwin_text_proc, 12, 119, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Master Sword", NULL, NULL },
12066 { jwin_text_proc, 160, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Sword Beam", NULL, NULL },
12067 { jwin_text_proc, 160, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "White Sword Beam", NULL, NULL },
12068 { jwin_text_proc, 160, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Magic Sword Beam", NULL, NULL },
12069 { jwin_text_proc, 160, 119, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Master Sword Beam", NULL, NULL },
12070 //26
12071 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Stairs", NULL, NULL },
12072 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Reflected Fireball", NULL, NULL },
12073 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Hookshot", NULL, NULL },
12074 { jwin_text_proc, 12, 119, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Wand", NULL, NULL },
12075 { jwin_text_proc, 12, 141, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Hammer", NULL, NULL },
12076 { jwin_text_proc, 12, 163, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Any Weapon", NULL, NULL },
12077 //32
12078 { jwin_ctext_proc, 235, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Flags 16-31", NULL, NULL },
12079 { jwin_text_proc, 87, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Secrets->Next (Flag only)", NULL, NULL },
12080 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 03", NULL, NULL },
12081 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 04", NULL, NULL },
12082 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 05", NULL, NULL },
12083 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 06", NULL, NULL },
12084 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 07", NULL, NULL },
12085 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 08", NULL, NULL },
12086 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 09", NULL, NULL },
12087 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 10", NULL, NULL },
12088 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 11", NULL, NULL },
12089 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 12", NULL, NULL },
12090 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 13", NULL, NULL },
12091 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 14", NULL, NULL },
12092 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 15", NULL, NULL },
12093 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 16", NULL, NULL },
12094 //48 (burn)
12095 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12096 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12097 { jwin_frame_proc, 108, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12098 { jwin_frame_proc, 108, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12099 //52 (arrow)
12100 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12101 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12102 { jwin_frame_proc, 108, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12103 //55 (bomb)
12104 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12105 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12106 //57 (boomerang)
12107 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12108 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12109 { jwin_frame_proc, 108, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12110 //60 (magic)
12111 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12112 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12113 //62 (sword)
12114 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12115 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12116 { jwin_frame_proc, 108, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12117 { jwin_frame_proc, 108, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12118 { jwin_frame_proc, 256, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12119 { jwin_frame_proc, 256, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12120 { jwin_frame_proc, 256, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12121 { jwin_frame_proc, 256, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12122 //70 (misc)
12123 { jwin_frame_proc, 63, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12124 { jwin_frame_proc, 63, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12125 { jwin_frame_proc, 63, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12126 { jwin_frame_proc, 63, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12127 { jwin_frame_proc, 63, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12128 { jwin_frame_proc, 63, 157, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12129 //76 (16-32)
12130 { jwin_frame_proc, 192, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12131 { jwin_frame_proc, 214, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12132 { jwin_frame_proc, 236, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12133 { jwin_frame_proc, 258, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12134 { jwin_frame_proc, 192, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12135 { jwin_frame_proc, 214, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12136 { jwin_frame_proc, 236, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12137 { jwin_frame_proc, 258, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12138 { jwin_frame_proc, 192, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12139 { jwin_frame_proc, 214, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12140 { jwin_frame_proc, 236, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12141 { jwin_frame_proc, 258, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12142 { jwin_frame_proc, 192, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12143 { jwin_frame_proc, 214, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12144 { jwin_frame_proc, 236, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12145 { jwin_frame_proc, 258, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12146
12147 //92 (burn)
12148 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12149 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12150 { d_scombo_proc, 110, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12151 { d_scombo_proc, 110, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12152 //96 (arrow)
12153 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12154 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12155 { d_scombo_proc, 110, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12156 //99 (bomb)
12157 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12158 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12159 //101 (boomerang)
12160 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12161 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12162 { d_scombo_proc, 110, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12163 //104 (magic)
12164 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12165 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12166 //106 (sword)
12167 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12168 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12169 { d_scombo_proc, 110, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12170 { d_scombo_proc, 110, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12171 { d_scombo_proc, 258, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12172 { d_scombo_proc, 258, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12173 { d_scombo_proc, 258, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12174 { d_scombo_proc, 258, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12175 //114 (misc)
12176 { d_scombo_proc, 65, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12177 { d_scombo_proc, 65, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12178 { d_scombo_proc, 65, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12179 { d_scombo_proc, 65, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12180 { d_scombo_proc, 65, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12181 { d_scombo_proc, 65, 159, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12182 //120 (16-32)
12183 { d_scombo_proc, 194, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12184 { d_scombo_proc, 216, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12185 { d_scombo_proc, 238, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12186 { d_scombo_proc, 260, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12187 { d_scombo_proc, 194, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12188 { d_scombo_proc, 216, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12189 { d_scombo_proc, 238, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12190 { d_scombo_proc, 260, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12191 { d_scombo_proc, 194, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12192 { d_scombo_proc, 216, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12193 { d_scombo_proc, 238, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12194 { d_scombo_proc, 260, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12195 { d_scombo_proc, 194, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12196 { d_scombo_proc, 216, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12197 { d_scombo_proc, 238, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12198 { d_scombo_proc, 260, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12199 //136 Secrets->Next
12200 { jwin_frame_proc, 158, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12201 { d_scombo_proc, 160, 49, 16, 16, 0, 1, 0, 0, 0, 0, NULL, NULL, NULL },
12202 //138
12203 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *) onHelp, NULL, NULL },
12204 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 'f', 0, 0, 0, (void *) onSecretF, NULL, NULL },
12205 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12206 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
12207 };
12208
12209 int32_t onSecretF()
12210 {
12211 Flags^=cFLAGS;
12212 object_message(secret_dlg+1, MSG_DRAW, 0);
12213 return D_O_K;
12214 }
12215
12216
12217 int32_t onSecretCombo()
12218 {
12219 secret_dlg[0].dp2=get_zc_font(font_lfont);
12220
12221
12222 mapscr *s;
12223
12224 if(CurrentLayer==0)
12225 {
12226 s=Map.CurrScr();
12227 }
12228 else
12229 {
12230 // s=TheMaps[(Map.CurrScr()->layermap[CurrentLayer-1]-1)*MAPSCRS+(Map.CurrScr()->layerscreen[CurrentLayer-1])];
12231 s=Map.AbsoluteScr((Map.CurrScr()->layermap[CurrentLayer-1]-1), (Map.CurrScr()->layerscreen[CurrentLayer-1]));
12232 }
12233 if(!s) return D_O_K;
12234
12235 char secretcombonumstr[27];
12236 sprintf(secretcombonumstr,"Secret Combos for Layer %d", CurrentLayer);
12237 secret_dlg[0].dp = secretcombonumstr;
12238
12239 secret_dlg[92].d1 = s->secretcombo[sBCANDLE];
12240 secret_dlg[92].fg = s->secretcset[sBCANDLE];
12241 secret_dlg[92].d2 = s->secretflag[sBCANDLE];
12242
12243 secret_dlg[93].d1 = s->secretcombo[sRCANDLE];
12244 secret_dlg[93].fg = s->secretcset[sRCANDLE];
12245 secret_dlg[93].d2 = s->secretflag[sRCANDLE];
12246
12247 secret_dlg[94].d1 = s->secretcombo[sWANDFIRE];
12248 secret_dlg[94].fg = s->secretcset[sWANDFIRE];
12249 secret_dlg[94].d2 = s->secretflag[sWANDFIRE];
12250
12251 secret_dlg[95].d1 = s->secretcombo[sDIVINEFIRE];
12252 secret_dlg[95].fg = s->secretcset[sDIVINEFIRE];
12253 secret_dlg[95].d2 = s->secretflag[sDIVINEFIRE];
12254
12255 secret_dlg[96].d1 = s->secretcombo[sARROW];
12256 secret_dlg[96].fg = s->secretcset[sARROW];
12257 secret_dlg[96].d2 = s->secretflag[sARROW];
12258
12259 secret_dlg[97].d1 = s->secretcombo[sSARROW];
12260 secret_dlg[97].fg = s->secretcset[sSARROW];
12261 secret_dlg[97].d2 = s->secretflag[sSARROW];
12262
12263 secret_dlg[98].d1 = s->secretcombo[sGARROW];
12264 secret_dlg[98].fg = s->secretcset[sGARROW];
12265 secret_dlg[98].d2 = s->secretflag[sGARROW];
12266
12267 secret_dlg[99].d1 = s->secretcombo[sBOMB];
12268 secret_dlg[99].fg = s->secretcset[sBOMB];
12269 secret_dlg[99].d2 = s->secretflag[sBOMB];
12270
12271 secret_dlg[100].d1 = s->secretcombo[sSBOMB];
12272 secret_dlg[100].fg = s->secretcset[sSBOMB];
12273 secret_dlg[100].d2 = s->secretflag[sSBOMB];
12274
12275 for(int32_t i=0; i<3; i++)
12276 {
12277 secret_dlg[101+i].d1 = s->secretcombo[sBRANG+i];
12278 secret_dlg[101+i].fg = s->secretcset[sBRANG+i];
12279 secret_dlg[101+i].d2 = s->secretflag[sBRANG+i];
12280 }
12281
12282 for(int32_t i=0; i<2; i++)
12283 {
12284 secret_dlg[104+i].d1 = s->secretcombo[sWANDMAGIC+i];
12285 secret_dlg[104+i].fg = s->secretcset[sWANDMAGIC+i];
12286 secret_dlg[104+i].d2 = s->secretflag[sWANDMAGIC+i];
12287 }
12288
12289 for(int32_t i=0; i<8; i++)
12290 {
12291 secret_dlg[106+i].d1 = s->secretcombo[sSWORD+i];
12292 secret_dlg[106+i].fg = s->secretcset[sSWORD+i];
12293 secret_dlg[106+i].d2 = s->secretflag[sSWORD+i];
12294 }
12295
12296 secret_dlg[114].d1 = s->secretcombo[sSTAIRS];
12297 secret_dlg[114].fg = s->secretcset[sSTAIRS];
12298 secret_dlg[114].d2 = s->secretflag[sSTAIRS];
12299
12300 secret_dlg[115].d1 = s->secretcombo[sREFFIREBALL];
12301 secret_dlg[115].fg = s->secretcset[sREFFIREBALL];
12302 secret_dlg[115].d2 = s->secretflag[sREFFIREBALL];
12303
12304 for(int32_t i=0; i<4; i++)
12305 {
12306 secret_dlg[116+i].d1 = s->secretcombo[sHOOKSHOT+i];
12307 secret_dlg[116+i].fg = s->secretcset[sHOOKSHOT+i];
12308 secret_dlg[116+i].d2 = s->secretflag[sHOOKSHOT+i];
12309 }
12310
12311 for(int32_t i=0; i<16; i++)
12312 {
12313 secret_dlg[120+i].d1 = s->secretcombo[sSECRET01+i];
12314 secret_dlg[120+i].fg = s->secretcset[sSECRET01+i];
12315 secret_dlg[120+i].d2 = s->secretflag[sSECRET01+i];
12316 }
12317
12318 //Sec->Next doesn't have a combo/cset value associated
12319 secret_dlg[137].d1 = 0;
12320 secret_dlg[137].fg = 0;
12321 secret_dlg[137].d2 = s->secretflag[sSECNEXT];
12322
12323 large_dialog(secret_dlg,1.75);
12324
12325 for(int32_t q = 0; secret_dlg[q].proc != NULL; ++q)
12326 {
12327 if(secret_dlg[q].proc == jwin_frame_proc)
12328 secret_dlg[q].w = secret_dlg[q].h = 36;
12329 }
12330
12331 if(do_zqdialog(secret_dlg,3) == 2)
12332 {
12333 mark_save_dirty();
12334 s->secretcombo[sBCANDLE] = secret_dlg[92].d1;
12335 s->secretcset[sBCANDLE] = secret_dlg[92].fg;
12336 s->secretflag[sBCANDLE] = secret_dlg[92].d2;
12337
12338 s->secretcombo[sRCANDLE] = secret_dlg[93].d1;
12339 s->secretcset[sRCANDLE] = secret_dlg[93].fg;
12340 s->secretflag[sRCANDLE] = secret_dlg[93].d2;
12341
12342 s->secretcombo[sWANDFIRE] = secret_dlg[94].d1;
12343 s->secretcset[sWANDFIRE] = secret_dlg[94].fg;
12344 s->secretflag[sWANDFIRE] = secret_dlg[94].d2;
12345
12346 s->secretcombo[sDIVINEFIRE] = secret_dlg[95].d1;
12347 s->secretcset[sDIVINEFIRE] = secret_dlg[95].fg;
12348 s->secretflag[sDIVINEFIRE] = secret_dlg[95].d2;
12349
12350 s->secretcombo[sARROW] = secret_dlg[96].d1;
12351 s->secretcset[sARROW] = secret_dlg[96].fg;
12352 s->secretflag[sARROW] = secret_dlg[96].d2;
12353
12354 s->secretcombo[sSARROW] = secret_dlg[97].d1;
12355 s->secretcset[sSARROW] = secret_dlg[97].fg;
12356 s->secretflag[sSARROW] = secret_dlg[97].d2;
12357
12358 s->secretcombo[sGARROW] = secret_dlg[98].d1;
12359 s->secretcset[sGARROW] = secret_dlg[98].fg;
12360 s->secretflag[sGARROW] = secret_dlg[98].d2;
12361
12362 s->secretcombo[sBOMB] = secret_dlg[99].d1;
12363 s->secretcset[sBOMB] = secret_dlg[99].fg;
12364 s->secretflag[sBOMB] = secret_dlg[99].d2;
12365
12366 s->secretcombo[sSBOMB] = secret_dlg[100].d1;
12367 s->secretcset[sSBOMB] = secret_dlg[100].fg;
12368 s->secretflag[sSBOMB] = secret_dlg[100].d2;
12369
12370 for(int32_t i=0; i<3; i++)
12371 {
12372 s->secretcombo[sBRANG+i] = secret_dlg[101+i].d1;
12373 s->secretcset[sBRANG+i] = secret_dlg[101+i].fg;
12374 s->secretflag[sBRANG+i] = secret_dlg[101+i].d2;
12375 }
12376
12377 for(int32_t i=0; i<2; i++)
12378 {
12379 s->secretcombo[sWANDMAGIC+i] = secret_dlg[104+i].d1;
12380 s->secretcset[sWANDMAGIC+i] = secret_dlg[104+i].fg;
12381 s->secretflag[sWANDMAGIC+i] = secret_dlg[104+i].d2;
12382 }
12383
12384 for(int32_t i=0; i<8; i++)
12385 {
12386 s->secretcombo[sSWORD+i] = secret_dlg[106+i].d1;
12387 s->secretcset[sSWORD+i] = secret_dlg[106+i].fg;
12388 s->secretflag[sSWORD+i] = secret_dlg[106+i].d2;
12389 }
12390
12391 s->secretcombo[sSTAIRS] = secret_dlg[114].d1;
12392 s->secretcset[sSTAIRS] = secret_dlg[114].fg;
12393 s->secretflag[sSTAIRS] = secret_dlg[114].d2;
12394
12395 s->secretcombo[sREFFIREBALL] = secret_dlg[115].d1;
12396 s->secretcset[sREFFIREBALL] = secret_dlg[115].fg;
12397 s->secretflag[sREFFIREBALL] = secret_dlg[115].d2;
12398
12399 for(int32_t i=0; i<4; i++)
12400 {
12401 s->secretcombo[sHOOKSHOT+i] = secret_dlg[116+i].d1;
12402 s->secretcset[sHOOKSHOT+i] = secret_dlg[116+i].fg;
12403 s->secretflag[sHOOKSHOT+i] = secret_dlg[116+i].d2;
12404 }
12405
12406 for(int32_t i=0; i<16; i++)
12407 {
12408 s->secretcombo[sSECRET01+i] = secret_dlg[120+i].d1;
12409 s->secretcset[sSECRET01+i] = secret_dlg[120+i].fg;
12410 s->secretflag[sSECRET01+i] = secret_dlg[120+i].d2;
12411 }
12412 s->secretflag[sSECNEXT] = secret_dlg[137].d2;
12413
12414 }
12415
12416 return D_O_K;
12417 }
12418
12419 void call_undercombo_dlg(int map, int screen);
12420 int32_t onUnderCombo()
12421 {
12422 call_undercombo_dlg(Map.getCurrMap(), Map.getCurrScr());
12423 return D_O_K;
12424 }
12425
12426 static DIALOG list_dlg[] =
12427 {
12428 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
12429 12 { jwin_win_proc, 60-12, 40, 200+24, 148, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
12430 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12431 12 { jwin_list_proc, 72-12-4, 60+4, 176+24+8, 92+3, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, NULL, NULL, NULL },
12432 12 { jwin_button_proc, 90, 163, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
12433 12 { jwin_button_proc, 170, 163, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
12434 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
12435 };
12436
12437 /*
12438 typedef struct item_struct {
12439 char *s;
12440 int32_t i;
12441 } item_struct;
12442 */
12443 item_struct bii[MAXITEMS+1];
12444 int32_t bii_cnt=-1;
12445
12446 void build_bii_list(bool usenone)
12447 {
12448 int32_t start=bii_cnt=0;
12449
12450 if(usenone)
12451 {
12452 bii[0].s = (char *)"(None)";
12453 bii[0].i = -2;
12454 bii_cnt=start=1;
12455 }
12456
12457 for(int32_t i=0; i<MAXITEMS; i++)
12458 {
12459 bii[bii_cnt].s = item_string[i];
12460 bii[bii_cnt].i = i;
12461 ++bii_cnt;
12462 }
12463
12464 for(int32_t i=start; i<bii_cnt-1; i++)
12465 {
12466 for(int32_t j=i+1; j<bii_cnt; j++)
12467 {
12468 if(stricmp(bii[i].s,bii[j].s)>0 && strcmp(bii[j].s,""))
12469 {
12470 zc_swap(bii[i],bii[j]);
12471 }
12472 }
12473 }
12474 }
12475
12476 const char *itemlist_num(int32_t index, int32_t *list_size)
12477 {
12478 if(index<0)
12479 {
12480 *list_size = bii_cnt;
12481 return NULL;
12482 }
12483 static char biin_buf[64+6];
12484 if(bii[index].i < 0)
12485 return bii[index].s;
12486 sprintf(biin_buf, "%s (%03d)", bii[index].s, bii[index].i);
12487 return biin_buf;
12488 }
12489
12490 weapon_struct biw[MAXWPNS];
12491 int32_t biw_cnt=-1;
12492
12493 void build_biw_list()
12494 {
12495 int32_t start=biw_cnt=0;
12496
12497 for(int32_t i=start; i<MAXWPNS; i++)
12498 {
12499 biw[biw_cnt].s = (char *)weapon_string[i];
12500 biw[biw_cnt].i = i;
12501 ++biw_cnt;
12502 }
12503
12504 for(int32_t i=start; i<biw_cnt-1; i++)
12505 {
12506 for(int32_t j=i+1; j<biw_cnt; j++)
12507 if(stricmp(biw[i].s,biw[j].s)>0 && strcmp(biw[j].s,""))
12508 zc_swap(biw[i],biw[j]);
12509 }
12510 }
12511
12512 int32_t writeoneweapon(PACKFILE *f, int32_t index)
12513 {
12514 dword section_version=V_WEAPONS;
12515 int32_t zversion = ZELDA_VERSION;
12516 int32_t zbuild = VERSION_BUILD;
12517 int32_t iid = biw[index].i;
12518 al_trace("Writing Weapon Sprite .zwpnspr file for weapon id: %d\n", iid);
12519
12520 //section version info
12521 if(!p_iputl(zversion,f))
12522 {
12523 return 0;
12524 }
12525 if(!p_iputl(zbuild,f))
12526 {
12527 return 0;
12528 }
12529 if(!p_iputw(section_version,f))
12530 {
12531 return 0;
12532 }
12533
12534 if(!write_deprecated_section_cversion(section_version, f))
12535 {
12536 return 0;
12537 }
12538
12539 //weapon string
12540
12541 if(!pfwrite((char *)weapon_string[iid], 64, f))
12542 {
12543 return 0;
12544 }
12545
12546 if(!p_putc(wpnsbuf[iid].misc,f))
12547 {
12548 return 0;
12549 }
12550
12551 if(!p_putc(wpnsbuf[iid].csets,f))
12552 {
12553 return 0;
12554 }
12555
12556 if(!p_putc(wpnsbuf[iid].frames,f))
12557 {
12558 return 0;
12559 }
12560
12561 if(!p_putc(wpnsbuf[iid].speed,f))
12562 {
12563 return 0;
12564 }
12565
12566 if(!p_putc(wpnsbuf[iid].type,f))
12567 {
12568 return 0;
12569 }
12570
12571 if(!p_iputw(wpnsbuf[iid].script,f))
12572 {
12573 return 0;
12574 }
12575
12576 //2.55 starts here
12577 if(!p_iputl(wpnsbuf[iid].tile,f))
12578 {
12579 return 0;
12580 }
12581
12582 return 1;
12583 }
12584
12585
12586 int32_t readoneweapon(PACKFILE *f, int32_t index)
12587 {
12588 dword section_version = 0;
12589 int32_t zversion = 0;
12590 int32_t zbuild = 0;
12591 wpndata tempwpnspr;
12592 memset(&tempwpnspr, 0, sizeof(wpndata));
12593
12594
12595 //char dmapstring[64]={0};
12596 //section version info
12597 if(!p_igetl(&zversion,f))
12598 {
12599 return 0;
12600 }
12601 if(!p_igetl(&zbuild,f))
12602 {
12603 return 0;
12604 }
12605 if(!p_igetw(&section_version,f))
12606 {
12607 return 0;
12608 }
12609 if(!read_deprecated_section_cversion(f))
12610 {
12611 return 0;
12612 }
12613 al_trace("readoneweapon section_version: %d\n", section_version);
12614
12615 if ( zversion > ZELDA_VERSION )
12616 {
12617 al_trace("Cannot read .zwpnspr packfile made in ZC version (%x) in this version of ZC (%x)\n", zversion, ZELDA_VERSION);
12618 return 0;
12619 }
12620
12621 else if ( ( section_version > V_WEAPONS ) )
12622 {
12623 al_trace("Cannot read .zwpnspr packfile made using V_WEAPONS (%d)\n", section_version);
12624 return 0;
12625
12626 }
12627 else
12628 {
12629 al_trace("Reading a .zwpnspr packfile made in ZC Version: %x, Build: %d\n", zversion, zbuild);
12630 }
12631
12632 char tmp_wpn_name[64];
12633 memset(tmp_wpn_name,0,64);
12634 if(!pfread(&tmp_wpn_name, 64, f))
12635 {
12636 return 0;
12637 }
12638
12639 word oldtile = 0;
12640 if(section_version < 8)
12641 if(!p_igetw(&oldtile,f))
12642 return 0;
12643
12644 if(!p_getc(&tempwpnspr.misc,f))
12645 {
12646 return 0;
12647 }
12648
12649 if(!p_getc(&tempwpnspr.csets,f))
12650 {
12651 return 0;
12652 }
12653
12654 if(!p_getc(&tempwpnspr.frames,f))
12655 {
12656 return 0;
12657 }
12658
12659 if(!p_getc(&tempwpnspr.speed,f))
12660 {
12661 return 0;
12662 }
12663
12664 if(!p_getc(&tempwpnspr.type,f))
12665 {
12666 return 0;
12667 }
12668
12669 if(!p_igetw(&tempwpnspr.script,f))
12670 {
12671 return 0;
12672 }
12673
12674 //2.55 starts here
12675 if ( zversion >= 0x255 )
12676 {
12677 if ( section_version >= 7 )
12678 {
12679 if(!p_igetl(&tempwpnspr.tile,f))
12680 {
12681 return 0;
12682 }
12683 }
12684 }
12685 if ( zversion < 0x255 )
12686 {
12687 tempwpnspr.tile = oldtile;
12688 }
12689 ::memcpy( &(wpnsbuf[biw[index].i]),&tempwpnspr, sizeof(wpndata));
12690 ::memcpy(weapon_string[biw[index].i], tmp_wpn_name, 64);
12691
12692 return 1;
12693 }
12694
12695 static int32_t seldata_copy;
12696 static void (*seldata_paste_func)(int32_t, int32_t);
12697
12698 void seldata_rclick_func(int32_t index, int32_t x, int32_t y)
12699 {
12700 NewMenu rcmenu {
12701 { "&Copy", [&](){seldata_copy = index;} },
12702 { "Paste", "&v", [&]()
12703 {
12704 seldata_paste_func(seldata_copy, index);
12705 mark_save_dirty();
12706 }, 0, seldata_copy < 0 ? MFL_DIS : 0 },
12707 };
12708 rcmenu.pop(x, y);
12709 }
12710
12711 int32_t select_data(const char *prompt,int32_t index,const char *(proc)(int32_t,int32_t*), FONT *title_font, void (*copyFunc)(int32_t, int32_t))
12712 {
12713 if(proc==NULL)
12714 return -1;
12715
12716 list_dlg[0].dp=(void *)prompt;
12717 list_dlg[0].dp2=title_font;
12718 list_dlg[2].d1=index;
12719 ListData select_list(proc, &font);
12720 list_dlg[2].dp=(void *) &select_list;
12721
12722 large_dialog(list_dlg);
12723
12724 seldata_copy=-1;
12725 seldata_paste_func=copyFunc;
12726 if(copyFunc)
12727 {
12728 list_dlg[2].flags|=D_USER<<1;
12729 list_dlg[2].dp3=(void*)seldata_rclick_func;
12730 }
12731 else
12732 {
12733 list_dlg[2].flags&=~(D_USER<<1);
12734 list_dlg[2].dp3=0;
12735 }
12736
12737 int32_t ret=do_zqdialog(list_dlg,2);
12738
12739 if(ret==0||ret==4)
12740 {
12741 position_mouse_z(0);
12742 return -1;
12743 }
12744
12745 return list_dlg[2].d1;
12746 }
12747
12748 int32_t select_data(const char *prompt,int32_t index,const char *(proc)(int32_t,int32_t*), const char *b1, const char *b2, FONT *title_font, void (*copyFunc)(int32_t, int32_t))
12749 {
12750 if(proc==NULL)
12751 return -1;
12752
12753 list_dlg[0].dp=(void *)prompt;
12754 list_dlg[0].dp2=title_font;
12755 list_dlg[2].d1=index;
12756 ListData select_data_list(proc, &font);
12757 list_dlg[2].dp=(void *) &select_data_list;
12758 list_dlg[3].dp=(void *)b1;
12759 list_dlg[4].dp=(void *)b2;
12760
12761 large_dialog(list_dlg);
12762
12763 seldata_copy=-1;
12764 seldata_paste_func=copyFunc;
12765 if(copyFunc)
12766 {
12767 list_dlg[2].flags|=D_USER<<1;
12768 list_dlg[2].dp3=(void*)seldata_rclick_func;
12769 }
12770 else
12771 {
12772 list_dlg[2].flags&=~(D_USER<<1);
12773 list_dlg[2].dp3=0;
12774 }
12775
12776 int32_t ret = do_zqdialog(list_dlg,2);
12777 list_dlg[3].dp=(void *) "OK";
12778 list_dlg[4].dp=(void *) "Cancel";
12779
12780 if(ret==0||ret==4)
12781 {
12782 position_mouse_z(0);
12783 return -1;
12784 }
12785
12786 position_mouse_z(0);
12787 return list_dlg[2].d1;
12788 }
12789
12790 int32_t onScreenScript()
12791 {
12792 call_screendata_dialog(7);
12793 return D_O_K;
12794 }
12795
12796 int32_t onScrData()
12797 {
12798 restore_mouse();
12799 call_screendata_dialog();
12800 return D_O_K;
12801 }
12802
12803 static char number_str_buf[MIDI_TRACK_BUFFER_SIZE];
12804 int32_t number_list_size=1;
12805 bool number_list_zero=false;
12806
12807 const char *numberlist(int32_t index, int32_t *list_size)
12808 {
12809 if(index>=0)
12810 {
12811 bound(index,0,number_list_size-1);
12812 sprintf(number_str_buf,"%d",index+(number_list_zero?0:1));
12813 return number_str_buf;
12814 }
12815
12816 *list_size=number_list_size;
12817 return NULL;
12818 }
12819
12820 static char dmap_str_buf[37];
12821 int32_t dmap_list_size=MAXDMAPS;
12822 bool dmap_list_zero=true;
12823
12824 const char *dmaplist(int32_t index, int32_t *list_size)
12825 {
12826 if(index>=0)
12827 {
12828 bound(index,0,dmap_list_size-1);
12829 sprintf(dmap_str_buf,"%3d-%s",index+(dmap_list_zero?0:1), DMaps[index].name);
12830 return dmap_str_buf;
12831 }
12832
12833 *list_size=dmap_list_size;
12834 return NULL;
12835 }
12836
12837 const char *gotomaplist(int32_t index, int32_t *list_size)
12838 {
12839 if(index>=0)
12840 {
12841 bound(index,0,map_count-1);
12842 sprintf(number_str_buf,"%d",index+1);
12843 return number_str_buf;
12844 }
12845
12846 *list_size = map_count;
12847 return NULL;
12848 }
12849
12850 const char *midilist(int32_t index, int32_t *list_size)
12851 {
12852 if(index>=0)
12853
12854 {
12855 bound(index,0,MAXCUSTOMMIDIS_ZQ-1);
12856 return midi_string[index];
12857 }
12858
12859 *list_size=MAXCUSTOMMIDIS_ZQ;
12860 return NULL;
12861 }
12862
12863 const char *levelnumlist(int32_t index, int32_t *list_size)
12864 {
12865 if(index>=0)
12866 {
12867 bound(index,0,0xFFF);
12868 sprintf(number_str_buf,"%.3X - %s",index,palnames[index]);
12869 return number_str_buf;
12870 }
12871
12872 *list_size=MAXLEVELS;
12873 return NULL;
12874 }
12875
12876 static char shop_str_buf[40];
12877 int32_t shop_list_size=1;
12878
12879 const char *shoplist(int32_t index, int32_t *list_size)
12880 {
12881 if(index>=0)
12882 {
12883 bound(index,0,shop_list_size-1);
12884 sprintf(shop_str_buf,"%3d: %s",index,QMisc.shop[index].name);
12885 return shop_str_buf;
12886 }
12887
12888 *list_size=shop_list_size;
12889 return NULL;
12890 }
12891
12892 static char bottle_str_buf[40];
12893 int32_t bottle_list_size=1;
12894
12895 const char *bottlelist(int32_t index, int32_t *list_size)
12896 {
12897 if(index>=0)
12898 {
12899 bound(index,0,bottle_list_size-1);
12900 sprintf(bottle_str_buf,"%2d: %s",index+1,QMisc.bottle_types[index].name);
12901 return bottle_str_buf;
12902 }
12903
12904 *list_size=bottle_list_size;
12905 return NULL;
12906 }
12907
12908 static char bottleshop_str_buf[40];
12909 int32_t bottleshop_list_size=1;
12910
12911 const char *bottleshoplist(int32_t index, int32_t *list_size)
12912 {
12913 if(index>=0)
12914 {
12915 bound(index,0,bottleshop_list_size-1);
12916 sprintf(bottleshop_str_buf,"%3d: %s",index,QMisc.bottle_shop_types[index].name);
12917 return bottleshop_str_buf;
12918 }
12919
12920 *list_size=bottleshop_list_size;
12921 return NULL;
12922 }
12923
12924 static char info_str_buf[40];
12925 int32_t info_list_size=1;
12926
12927 const char *infolist(int32_t index, int32_t *list_size)
12928 {
12929 if(index>=0)
12930 {
12931 bound(index,0,info_list_size-1);
12932 sprintf(info_str_buf,"%3d: %s",index,QMisc.info[index].name);
12933 return info_str_buf;
12934 }
12935
12936 *list_size=info_list_size;
12937 return NULL;
12938 }
12939
12940 bool mapcount_will_affect_layers(word newmapcount)
12941 {
12942 for(int32_t i=0; i<(newmapcount)*MAPSCRS; i++)
12943 {
12944 mapscr *layerchecker=&TheMaps[i];
12945
12946 for(int32_t j=0; j<6; j++)
12947 {
12948 if(layerchecker->layermap[j]>(newmapcount))
12949 {
12950 return true;
12951 }
12952 }
12953 }
12954 return false;
12955 }
12956
12957 void update_map_count(word newmapcount)
12958 {
12959 if(map_count == newmapcount) return;
12960 mark_save_dirty();
12961 setMapCount2(newmapcount);
12962 //Prevent the nine 'last mapscreen' buttons from pointing to invlid locations
12963 //if the user reduces the mapcount. -Z ( 23rd September, 2019 )
12964 for ( int32_t q = 0; q < 9; q++ )
12965 {
12966 map_page[q].map = ( map_page[q].map > newmapcount-1 ) ? newmapcount-1 : map_page[q].map;
12967 }
12968 for(int32_t i=0; i<(newmapcount)*MAPSCRS; i++)
12969 {
12970 fix_layers(&TheMaps[i], false);
12971 }
12972
12973 refresh(rMAP+rSCRMAP+rMENU);
12974 }
12975
12976 int32_t onGotoMap()
12977 {
12978 int32_t ret = select_data("Goto Map",Map.getCurrMap(),gotomaplist,get_zc_font(font_lfont));
12979
12980 if(ret >= 0)
12981 {
12982 int32_t m=Map.getCurrMap();
12983 Map.setCurrMap(ret);
12984 }
12985
12986 refresh(rALL);
12987 return D_O_K;
12988 }
12989
12990 int32_t onFlags()
12991 {
12992 restore_mouse();
12993 int32_t ret=select_cflag("Select Combo Flag",Flag);
12994 position_mouse_z(0);
12995
12996 if(ret>=0)
12997 {
12998 Flag=ret;
12999 refresh(rMENU);
13000 doflags();
13001 }
13002
13003 return D_O_K;
13004 }
13005
13006 static DIALOG usedcombo_list_dlg[] =
13007 {
13008 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
13009 12 { jwin_win_proc, 60-12, 40, 200+24, 148, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Combos Used", NULL, NULL },
13010 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
13011 12 { jwin_textbox_proc, 72-12, 60+4, 176+24+1, 92+4, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, NULL, NULL, NULL },
13012 12 { jwin_button_proc, 130, 163, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
13013 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
13014 };
13015
13016
13017
13018 int32_t onUsedCombos()
13019 {
13020 restore_mouse();
13021 usedcombo_list_dlg[0].dp2=get_zc_font(font_lfont);
13022
13023 int32_t usedcombos[7][300][2];
13024 char combolist_text[65536];
13025 char temptext[80];
13026
13027 int32_t drawmap=Map.getCurrMap();
13028 int32_t drawscr=Map.getCurrScr();
13029 int32_t counter[7];
13030
13031 for(int32_t layer=0; layer<7; ++layer)
13032 {
13033 counter[layer]=0;
13034
13035 if(layer==0)
13036 {
13037 drawmap=Map.getCurrMap();
13038 drawscr=Map.getCurrScr();
13039 }
13040 else
13041 {
13042 drawmap=Map.CurrScr()->layermap[layer-1]-1;
13043 drawscr=Map.CurrScr()->layerscreen[layer-1];
13044 }
13045 mapscr* draw_mapscr = Map.AbsoluteScr(drawmap, drawscr);
13046 if(!draw_mapscr) continue;
13047
13048 usedcombos[layer][0][0]=draw_mapscr->data[0];
13049 usedcombos[layer][0][1]=1;
13050 counter[layer]=1;
13051
13052 for(int32_t i=1; i<176; ++i)
13053 {
13054 bool used=false;
13055
13056 for(int32_t j=0; j<counter[layer]; ++j)
13057 {
13058 if(usedcombos[layer][j][0]==draw_mapscr->data[i])
13059 {
13060 ++usedcombos[layer][j][1];
13061 used=true;
13062 break;
13063 }
13064 }
13065
13066 if(!used)
13067 {
13068 usedcombos[layer][counter[layer]][0]=draw_mapscr->data[i];
13069 usedcombos[layer][counter[layer]][1]=1;
13070 ++counter[layer];
13071 }
13072 }
13073
13074 for(int32_t i=0; i<counter[layer]-1; i++)
13075 {
13076 for(int32_t j=i+1; j<counter[layer]; j++)
13077 {
13078 if(usedcombos[layer][i][0]>usedcombos[layer][j][0])
13079 {
13080 zc_swap(usedcombos[layer][i][0],usedcombos[layer][j][0]);
13081 zc_swap(usedcombos[layer][i][1],usedcombos[layer][j][1]);
13082 }
13083 }
13084 }
13085 }
13086
13087 sprintf(combolist_text, " ");
13088
13089 for(int32_t layer=0; layer<7; ++layer)
13090 {
13091 if(counter[layer]>0)
13092 {
13093 if(layer>0)
13094 {
13095 strcat(combolist_text, "\n");
13096 }
13097
13098 sprintf(temptext, "Combos on layer %d\n-----------------\n", layer);
13099 strcat(combolist_text, temptext);
13100
13101 for(int32_t i=0; i<counter[layer]; i++)
13102 {
13103 if((i<counter[layer]-1) && (((usedcombos[layer][i][1]==usedcombos[layer][i+1][1]&&(usedcombos[layer][i][0]+1==usedcombos[layer][i+1][0])) && ((i==0) || ((usedcombos[layer][i][1]!=usedcombos[layer][i-1][1])||((usedcombos[layer][i][0]-1!=usedcombos[layer][i-1][0])))))))
13104 {
13105 sprintf(temptext, "%5d ", usedcombos[layer][i][0]);
13106 strcat(combolist_text, temptext);
13107 }
13108 else if(((i>0) && (((usedcombos[layer][i][1]==usedcombos[layer][i-1][1])&&((usedcombos[layer][i][0]-1==usedcombos[layer][i-1][0]))) && ((i==counter[layer]-1) || ((usedcombos[layer][i][1]!=usedcombos[layer][i+1][1])||((usedcombos[layer][i][0]+1!=usedcombos[layer][i+1][0])))))))
13109 {
13110 sprintf(temptext, "- %5d (%3d)\n", usedcombos[layer][i][0],usedcombos[layer][i][1]);
13111 strcat(combolist_text, temptext);
13112 }
13113 else if(((i==0) && ((usedcombos[layer][i][1]!=usedcombos[layer][i+1][1])||((usedcombos[layer][i][0]+1!=usedcombos[layer][i+1][0]))))||
13114 ((i==counter[layer]-1) && ((usedcombos[layer][i][1]!=usedcombos[layer][i-1][1])||((usedcombos[layer][i][0]-1!=usedcombos[layer][i-1][0]))))||
13115 ((i>0) && (i<counter[layer]-1) && ((usedcombos[layer][i][1]!=usedcombos[layer][i+1][1])||((usedcombos[layer][i][0]+1!=usedcombos[layer][i+1][0]))) && ((usedcombos[layer][i][1]!=usedcombos[layer][i-1][1])||((usedcombos[layer][i][0]-1!=usedcombos[layer][i-1][0])))))
13116 {
13117 sprintf(temptext, " %5d (%3d)\n", usedcombos[layer][i][0],usedcombos[layer][i][1]);
13118 strcat(combolist_text, temptext);
13119 }
13120 }
13121 }
13122 }
13123
13124 strcat(combolist_text, "\n");
13125 usedcombo_list_dlg[2].dp=combolist_text;
13126 usedcombo_list_dlg[2].d2=0;
13127
13128 large_dialog(usedcombo_list_dlg);
13129
13130 do_zqdialog(usedcombo_list_dlg,2);
13131 position_mouse_z(0);
13132 return D_O_K;
13133 }
13134
13135 int32_t onItem()
13136 {
13137 restore_mouse();
13138 int32_t exit_status;
13139 int32_t current_item=Map.CurrScr()->hasitem != 0 ? Map.CurrScr()->item : -1;
13140
13141 ItemListerDialog(current_item,true).show();
13142 if(current_item != lister_sel_val)
13143 {
13144 if(lister_sel_val>=0)
13145 {
13146 mark_save_dirty();
13147 Map.CurrScr()->item = lister_sel_val;
13148 Map.CurrScr()->hasitem = true;
13149 }
13150 else
13151 {
13152 mark_save_dirty();
13153 Map.CurrScr()->hasitem = false;
13154 }
13155 }
13156
13157 refresh(rMAP+rMENU);
13158 return D_O_K;
13159 }
13160
13161 void call_room_dlg(mapscr* scr);
13162 int32_t onRoom()
13163 {
13164 restore_mouse();
13165 auto* scr = Map.CurrScr();
13166 call_room_dlg(scr);
13167
13168 refresh(rMAP+rMENU);
13169 return D_O_K;
13170 }
13171
13172 int32_t onEndString()
13173 {
13174 int32_t ret=select_data("Select Ending String",QMisc.endstring,msgslist,get_zc_font(font_lfont));
13175
13176 if(ret>=0)
13177 {
13178 mark_save_dirty();
13179 QMisc.endstring=msglistcache[ret];
13180 }
13181
13182 refresh(rMENU);
13183 return D_O_K;
13184 }
13185
13186 12 static ListData levelnum_list(levelnumlist, &font);
13187
13188 static DIALOG screen_pal_dlg[] =
13189 {
13190 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
13191 12 { jwin_win_proc, 60-12, 40, 200-16, 96, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Select Palette", NULL, NULL },
13192 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
13193 12 { jwin_droplist_proc, 72-12, 84+4, 161, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, (void *) &levelnum_list, NULL, NULL },
13194 12 { jwin_button_proc, 70, 111, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
13195 12 { jwin_button_proc, 150, 111, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
13196 12 { jwin_text_proc, 72-12, 60+4, 168, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Note: This does not affect how the", NULL, NULL },
13197 12 { jwin_text_proc, 72-12, 72+4, 168, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "room will be displayed in-game!", NULL, NULL },
13198 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
13199 };
13200 // return list_dlg[2].d1;
13201
13202 int32_t onScreenPalette()
13203 {
13204 restore_mouse();
13205 screen_pal_dlg[0].dp2=get_zc_font(font_lfont);
13206 auto oldcol = screen_pal_dlg[2].d1 = Map.getcolor();
13207
13208 large_dialog(screen_pal_dlg);
13209 auto old_valid = Map.CurrScr()->valid;
13210 pause_dlg_tint(true);
13211 zq_set_screen_never_freeze(true);
13212 while(true)
13213 {
13214 auto ret = do_zqdialog(screen_pal_dlg,2);
13215 if(ret == 2)
13216 {
13217 Map.setcolor(screen_pal_dlg[2].d1);
13218 refresh(rALL);
13219 }
13220 else
13221 {
13222 if(ret == 3)
13223 {
13224 if(screen_pal_dlg[2].d1 != oldcol)
13225 mark_save_dirty();
13226 Map.setcolor(screen_pal_dlg[2].d1);
13227 }
13228 else
13229 {
13230 Map.setcolor(oldcol);
13231 Map.CurrScr()->valid = old_valid;
13232 }
13233 refresh(rALL);
13234 break;
13235 }
13236 }
13237 pause_dlg_tint(false);
13238 zq_set_screen_never_freeze(false);
13239
13240 rebuild_trans_table();
13241
13242 return D_O_K;
13243 }
13244
13245 int32_t onDecScrPal()
13246 {
13247 if(DisableLPalShortcuts)
13248 {
13249 lpal_dsa();
13250 return D_O_K;
13251 }
13252 restore_mouse();
13253 int32_t c = Map.getcolor();
13254 c = (c+511) % 512;
13255 Map.setcolor(c);
13256 refresh(rALL);
13257 mark_save_dirty();
13258 return D_O_K;
13259 }
13260
13261 int32_t onIncScrPal()
13262 {
13263 if(DisableLPalShortcuts)
13264 {
13265 lpal_dsa();
13266 return D_O_K;
13267 }
13268 restore_mouse();
13269 int32_t c = Map.getcolor();
13270 c = (c+1)%512;
13271 Map.setcolor(c);
13272 refresh(rALL);
13273 mark_save_dirty();
13274 return D_O_K;
13275 }
13276
13277 int32_t PalWrap(int32_t kX, int32_t const kLowerBound, int32_t const kUpperBound)
13278 {
13279 int32_t range_size = kUpperBound - kLowerBound + 1;
13280
13281 if (kX < kLowerBound)
13282 kX += range_size * ((kLowerBound - kX) / range_size + 1);
13283
13284 return kLowerBound + (kX - kLowerBound) % range_size;
13285 }
13286
13287 int32_t onDecScrPal16()
13288 {
13289 if(DisableLPalShortcuts)
13290 {
13291 lpal_dsa();
13292 return D_O_K;
13293 }
13294 restore_mouse();
13295 int32_t c = Map.getcolor();
13296 c = PalWrap( ( c-0x10 ), 0, 511 );
13297 Map.setcolor(c);
13298 refresh(rALL);
13299 mark_save_dirty();
13300 return D_O_K;
13301 }
13302
13303 int32_t onIncScrPal16()
13304 {
13305 if(DisableLPalShortcuts)
13306 {
13307 lpal_dsa();
13308 return D_O_K;
13309 }
13310 restore_mouse();
13311 int32_t c = Map.getcolor();
13312 c = PalWrap( ( c+0x10 ), 0, 511 );
13313 Map.setcolor(c);
13314 refresh(rALL);
13315 mark_save_dirty();
13316 return D_O_K;
13317 }
13318
13319 int32_t onZoomIn()
13320 {
13321 change_mapscr_zoom(-1);
13322 return D_O_K;
13323 }
13324
13325 int32_t onZoomOut()
13326 {
13327 change_mapscr_zoom(1);
13328 return D_O_K;
13329 }
13330
13331 int32_t d_ndroplist_proc(int32_t msg,DIALOG *d,int32_t c)
13332 {
13333 int32_t ret = jwin_droplist_proc(msg,d,c);
13334
13335 // The only place this proc is used is in the info type editor.
13336 // If it's ever used anywhere else, this will probably need to be changed.
13337 // Maybe add a flag for it or something.
13338 int32_t msgID=msg_at_pos(d->d1);
13339
13340 switch(msg)
13341 {
13342 case MSG_DRAW:
13343 case MSG_CHAR:
13344 case MSG_CLICK:
13345 textprintf_ex(screen,font,d->x - 48,d->y + 4,jwin_pal[jcBOXFG],jwin_pal[jcBOX],"%5d",msgID);
13346 }
13347
13348 return ret;
13349 }
13350
13351 int32_t d_idroplist_proc(int32_t msg,DIALOG *d,int32_t c)
13352 {
13353 int32_t ret = jwin_droplist_proc(msg,d,c);
13354
13355 switch(msg)
13356 {
13357 case MSG_DRAW:
13358 case MSG_CHAR:
13359 case MSG_CLICK:
13360 int32_t tile = bii[d->d1].i >=0 ? itemsbuf[bii[d->d1].i].tile : 0;
13361 int32_t cset = bii[d->d1].i >=0 ? itemsbuf[bii[d->d1].i].csets&15 : 0;
13362 int32_t x = d->x + d->w + 4;
13363 int32_t y = d->y - 8;
13364 int32_t w = 32;
13365 int32_t h = 32;
13366
13367 BITMAP *buf = create_bitmap_ex(8,16,16);
13368 BITMAP *bigbmp = create_bitmap_ex(8,w,h);
13369
13370 if(buf && bigbmp)
13371 {
13372 clear_bitmap(buf);
13373
13374 if(tile)
13375 overtile16(buf, tile,0,0,cset,0);
13376
13377 stretch_blit(buf, bigbmp, 0,0, 16, 16, 0, 0, w, h);
13378 destroy_bitmap(buf);
13379 jwin_draw_frame(screen,x,y,w+4,h+4,FR_DEEP);
13380 blit(bigbmp,screen,0,0,x+2,y+2,w,h);
13381 destroy_bitmap(bigbmp);
13382 }
13383
13384 }
13385
13386 return ret;
13387 }
13388
13389 int32_t d_nidroplist_proc(int32_t msg,DIALOG *d,int32_t c)
13390 {
13391 int32_t ret = d_idroplist_proc(msg,d,c);
13392
13393 switch(msg)
13394 {
13395 case MSG_DRAW:
13396 case MSG_CHAR:
13397 case MSG_CLICK:
13398 textprintf_ex(screen,font,d->x - 48,d->y + 4,jwin_pal[jcBOXFG],jwin_pal[jcBOX],"%5d",bii[d->d1].i);
13399 }
13400
13401 return ret;
13402 }
13403
13404 // Triforce pieces
13405 static byte triframe_points[9*4] =
13406 {
13407 0,2,2,0, 2,0,4,2, 0,2,4,2, 1,1,3,1, 2,0,2,2,
13408 1,1,1,2, 1,1,2,2, 3,1,3,2, 3,1,2,2
13409 };
13410
13411 int32_t d_tri_frame_proc(int32_t msg,DIALOG *d,int32_t c)
13412 {
13413 //these are here to bypass compiler warnings about unused arguments
13414 c=c;
13415
13416 if(msg==MSG_DRAW)
13417 {
13418 int32_t x[5],y[3];
13419
13420 x[0]=d->x;
13421 x[1]=d->x+(d->w>>2);
13422 x[2]=d->x+(d->w>>1);
13423 x[3]=d->x+(d->w>>1)+(d->w>>2);
13424 x[4]=d->x+d->w;
13425 y[0]=d->y;
13426 y[1]=d->y+(d->h>>1);
13427 y[2]=d->y+d->h;
13428
13429 byte *p = triframe_points;
13430
13431 for(int32_t i=0; i<9; i++)
13432 {
13433 line(screen,x[*p],y[*(p+1)],x[*(p+2)],y[*(p+3)],d->fg);
13434 p+=4;
13435 }
13436 }
13437
13438 return D_O_K;
13439 }
13440
13441 int32_t d_tri_edit_proc(int32_t msg,DIALOG *d,int32_t c)
13442 {
13443 jwin_button_proc(msg,d,c);
13444
13445 if(msg==MSG_CLICK)
13446 {
13447 int v;
13448 if (auto num = call_get_num("Piece Number", d->d1, 8, 1))
13449 v = *num;
13450 else return D_O_K;
13451
13452 if(v!=d->d1)
13453 {
13454 DIALOG *tp = d - d->d2;
13455
13456 for(int32_t i=0; i<8; i++)
13457 {
13458 if(tp->d1==v)
13459 {
13460 tp->d1 = d->d1;
13461 ((char*)(tp->dp))[0] = d->d1+'0';
13462 jwin_button_proc(MSG_DRAW,tp,0);
13463 }
13464
13465 ++tp;
13466 }
13467
13468 d->d1 = v;
13469 ((char*)(d->dp))[0] = v+'0';
13470 }
13471
13472 d->flags = 0;
13473 jwin_button_proc(MSG_DRAW,d,0);
13474 }
13475
13476 return D_O_K;
13477 }
13478
13479 static DIALOG tp_dlg[] =
13480 {
13481 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
13482 12 { jwin_win_proc, 56, 32, 208, 160, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Triforce Pieces", NULL, NULL },
13483 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
13484 12 { d_tri_frame_proc, 64, 56, 192, 96, jwin_pal[jcBOXFG], jwin_pal[jcBOX], 0, 0, 0, 0, NULL, NULL, NULL },
13485 // 3
13486 12 { d_tri_edit_proc, 138, 82, 17, 17, vc(14), vc(1), 0, 0, 0, 0, (void *) "1", NULL, NULL },
13487 12 { d_tri_edit_proc, 166, 82, 17, 17, vc(14), vc(1), 0, 0, 0, 1, (void *) "2", NULL, NULL },
13488 12 { d_tri_edit_proc, 90, 130, 17, 17, vc(14), vc(1), 0, 0, 0, 2, (void *) "3", NULL, NULL },
13489 12 { d_tri_edit_proc, 214, 130, 17, 17, vc(14), vc(1), 0, 0, 0, 3, (void *) "4", NULL, NULL },
13490 // 7
13491 12 { d_tri_edit_proc, 138, 110, 17, 17, vc(14), vc(1), 0, 0, 0, 4, (void *) "5", NULL, NULL },
13492 12 { d_tri_edit_proc, 118, 130, 17, 17, vc(14), vc(1), 0, 0, 0, 5, (void *) "6", NULL, NULL },
13493 12 { d_tri_edit_proc, 166, 110, 17, 17, vc(14), vc(1), 0, 0, 0, 6, (void *) "7", NULL, NULL },
13494 12 { d_tri_edit_proc, 186, 130, 17, 17, vc(14), vc(1), 0, 0, 0, 7, (void *) "8", NULL, NULL },
13495 // 11
13496 12 { jwin_button_proc, 90, 166, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
13497 12 { jwin_button_proc, 170, 166, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
13498 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
13499 };
13500
13501 int32_t onTriPieces()
13502 {
13503 tp_dlg[0].dp2=get_zc_font(font_lfont);
13504 char temptext[8][2];
13505
13506 for(int32_t i=0; i<8; i++)
13507 {
13508 tp_dlg[i+3].d1 = QMisc.triforce[i];
13509 // ((char*)(tp_dlg[i+3].dp))[0] = QMisc.triforce[i]+'0';
13510 sprintf(temptext[i], "%d", QMisc.triforce[i]);
13511 tp_dlg[i+3].dp=temptext[i];
13512 }
13513
13514 large_dialog(tp_dlg);
13515
13516 if(do_zqdialog(tp_dlg,-1) == 11)
13517 {
13518 mark_save_dirty();
13519
13520 for(int32_t i=0; i<8; i++)
13521 QMisc.triforce[i] = tp_dlg[i+3].d1;
13522 }
13523
13524 return D_O_K;
13525 }
13526
13527 bool small_dmap=false;
13528
13529 int32_t d_hexedit_proc(int32_t msg,DIALOG *d,int32_t c)
13530 {
13531 return jwin_hexedit_proc(msg,d,c);
13532 }
13533
13534 void drawgrid(BITMAP *dest,int32_t x,int32_t y,int32_t grid,int32_t fg,int32_t bg,int32_t div)
13535 {
13536 if(div!=-1)
13537 rectfill(dest,x-1,y-1,x+63,y+3,div);
13538
13539 for(int32_t dx=0; dx<64; dx+=8)
13540 {
13541 if(grid&0x80)
13542 rectfill(dest,x+dx,y,x+dx+6,y+2,fg);
13543 else if(bg!=-1)
13544 rectfill(dest,x+dx,y,x+dx+6,y+2,bg);
13545
13546 grid<<=1;
13547 }
13548 }
13549
13550 void drawovergrid(BITMAP *dest,int32_t x,int32_t y,int32_t grid,int32_t color,int32_t div)
13551 {
13552 if(div!=-1)
13553 rectfill(dest,x-1,y-1,x+63,y+3,div);
13554
13555 for(int32_t dx=0; dx<64; dx+=4)
13556 {
13557 rectfill(dest,x+dx,y,x+dx+2,y+2,color);
13558 grid<<=1;
13559 }
13560 }
13561
13562 void drawgrid_s(BITMAP *dest,int32_t x,int32_t y,int32_t grid,int32_t fg,int32_t bg,int32_t div)
13563 {
13564 rectfill(dest,x-1,y-1,x+63,y+3,div);
13565
13566 for(int32_t dx=0; dx<64; dx+=8)
13567 {
13568 rectfill(dest,x+dx,y,x+dx+6,y+2,bg);
13569
13570 if(grid&0x80)
13571 rectfill(dest,x+dx+2,y,x+dx+4,y+2,fg);
13572
13573 grid<<=1;
13574 }
13575 }
13576
13577 void drawdmap(int32_t dmap)
13578 {
13579 int32_t c;
13580 zcolors mc=QMisc.colors;
13581
13582 switch((DMaps[dmap].type&dmfTYPE))
13583 {
13584 case dmDNGN:
13585 case dmCAVE:
13586 clear_bitmap(dmapbmp_small);
13587
13588 if(DMaps[dmap].minimap_tile[1])
13589 ;
13590 // overworld_map_tile overrides the NES minimap. dungeon_map_tile does not.
13591 else for(int32_t y=1; y<33; y+=4)
13592 drawgrid(dmapbmp_small,0,y,DMaps[dmap].grid[y>>2], DMaps[dmap].flags&dmfMINIMAPCOLORFIX ? mc.cave_fg : mc.dngn_fg, -1, -1);
13593
13594 c=DMaps[dmap].compass;
13595 // rectfill(dmapbmp,(c&15)*8+3,(c>>4)*4+1,(c&15)*8+5,(c>>4)*4+3,dvc(2*4));
13596 rectfill(dmapbmp_small,(c&15)*8+3,(c>>4)*4+1,(c&15)*8+5,(c>>4)*4+3,vc(4));
13597 c=DMaps[dmap].cont;
13598 rectfill(dmapbmp_small,(c&15)*8+3,(c>>4)*4+1,(c&15)*8+5,(c>>4)*4+3,vc(10));
13599 break;
13600
13601 case dmOVERW:
13602 clear_bitmap(dmapbmp_small);
13603
13604 if(DMaps[dmap].minimap_tile[1])
13605 ;
13606 else if(!mc.overworld_map_tile)
13607 for(int32_t y=1; y<33; y+=4)
13608 drawovergrid(dmapbmp_small,1,y,DMaps[dmap].grid[y>>2],mc.overw_bg,vc(0));
13609
13610 c=DMaps[dmap].cont;
13611 rectfill(dmapbmp_small,(c&15)*4+1,(c>>4)*4+1,(c&15)*4+3,(c>>4)*4+3,vc(10));
13612 break;
13613
13614 case dmBSOVERW:
13615 clear_bitmap(dmapbmp_small);
13616
13617 if(DMaps[dmap].minimap_tile[1])
13618 ;
13619 else if(!mc.overworld_map_tile)
13620 for(int32_t y=1; y<33; y+=4)
13621 // drawgrid_s(dmapbmp,1,y,DMaps[dmap].grid[y>>2],dvc(2*4),dvc(2*3),dvc(3+4));
13622 drawgrid_s(dmapbmp_small,0,y,DMaps[dmap].grid[y>>2],mc.bs_goal,mc.bs_dk,vc(14));
13623
13624 c=DMaps[dmap].cont;
13625 rectfill(dmapbmp_small,(c&15)*8+3,(c>>4)*4+1,(c&15)*8+5,(c>>4)*4+3,vc(10));
13626 break;
13627 }
13628 }
13629
13630 void drawdmap_screen(int32_t x, int32_t y, int32_t w, int32_t h, int32_t dmap)
13631 {
13632 BITMAP *tempbmp = create_bitmap_ex(8,w,h);
13633 clear_to_color(tempbmp, vc(0));
13634 zcolors mc=QMisc.colors;
13635
13636 // rectfill(tempbmp,x,y,x+w-1,y+h-1,vc(0));
13637
13638 if(DMaps[dmap].minimap_tile[1])
13639 {
13640 draw_block(tempbmp,0,0,DMaps[dmap].minimap_tile[1],DMaps[dmap].minimap_cset[1],5,3);
13641 }
13642 else if(((DMaps[dmap].type&dmfTYPE)==dmDNGN || (DMaps[dmap].type&dmfTYPE)==dmCAVE) && mc.dungeon_map_tile)
13643 {
13644 draw_block(tempbmp,0,0,mc.dungeon_map_tile,mc.dungeon_map_cset,5,3);
13645 }
13646 else if(((DMaps[dmap].type&dmfTYPE)==dmOVERW || (DMaps[dmap].type&dmfTYPE)==dmBSOVERW) && mc.overworld_map_tile)
13647 {
13648 draw_block(tempbmp,0,0,mc.overworld_map_tile,mc.overworld_map_cset,5,3);
13649 }
13650
13651 masked_blit(dmapbmp_small,tempbmp,0,0,8,7,65,33);
13652
13653 blit(tempbmp,screen,0,0,x,y,w,h);
13654 destroy_bitmap(tempbmp);
13655
13656 }
13657
13658 int32_t d_dropdmaplist_proc(int32_t msg,DIALOG *d,int32_t c)
13659 {
13660 if(msg==MSG_DRAW)
13661 {
13662 int32_t dmap = d->d1;
13663 int32_t *xy = (int32_t*)(d->dp3);
13664 float temp_scale = 1.5;
13665
13666 drawdmap(dmap);
13667
13668 if(xy[0]>-1000&&xy[1]>-1000)
13669 {
13670 int32_t x = d->x+int32_t((xy[0]-2)*temp_scale);
13671 int32_t y = d->y+int32_t((xy[1]-2)*temp_scale);
13672 int32_t w = 84;
13673 int32_t h = 52;
13674 jwin_draw_frame(screen,x,y,w,h,FR_DEEP);
13675 drawdmap_screen(x+2,y+2,w-4,h-4,dmap);
13676 }
13677
13678 if(xy[2]>-1000&&xy[3]>-1000)
13679 {
13680 textprintf_ex(screen,get_zc_font(font_lfont_l),d->x+int32_t((xy[2])*temp_scale),d->y+int32_t((xy[3])*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Map: %-3d",DMaps[d->d1].map+1);
13681 }
13682
13683 if(xy[4]>-1000&&xy[5]>-1000)
13684 {
13685 textprintf_ex(screen,get_zc_font(font_lfont_l),d->x+int32_t((xy[4])*temp_scale),d->y+int32_t((xy[5])*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Level: %-3d",DMaps[d->d1].level);
13686 }
13687 }
13688
13689 return jwin_droplist_proc(msg,d,c);
13690 }
13691
13692 void drawxmap(ALLEGRO_BITMAP* dest, int32_t themap, int32_t xoff, bool large, int dx, int dy)
13693 {
13694 ALLEGRO_STATE old_state;
13695 al_store_state(&old_state, ALLEGRO_STATE_TARGET_BITMAP);
13696
13697 al_set_target_bitmap(dest);
13698 al_clear_to_color(al_map_rgba(0, 0, 0, 0));
13699
13700 int32_t cols = (large ? 8 : 16);
13701 int32_t col_width = large ? 22 : 11;
13702 int32_t dot_width = (large ? 6 : 4);
13703 int32_t dot_offset = (large ? 7 : 3);
13704 int32_t l = 10;
13705
13706 for (int32_t y = 0; y < 8; y++)
13707 {
13708 // Users might have set the dmap to a map that has since been deleted.
13709 if (themap >= Map.getMapCount())
13710 break;
13711
13712 for (int32_t x = 0; x < cols; x++)
13713 {
13714 if (x + xoff < 0 || x + xoff > 15)
13715 continue;
13716
13717 const mapscr* scr = get_canonical_scr(themap, y * 16 + x + (large ? xoff : 0));
13718 if (!(scr->valid & mVALID))
13719 continue;
13720
13721 al_draw_filled_rectangle(dx + (x * col_width), dy + (y * l), dx + (x * col_width + col_width), dy + ((y * l) + l), real_lc1(scr->color));
13722 al_draw_filled_rectangle(dx + (x * col_width + dot_offset), dy + (y * l + 3), dx + (x * col_width + dot_offset + dot_width), dy + (y * l + l - 3), real_lc2(scr->color));
13723 }
13724 }
13725
13726 al_restore_state(&old_state);
13727 }
13728
13729 12 ListData dmap_list(dmaplist, &font);
13730
13731 12 static dmap copiedDMap;
13732 static byte dmapcopied = 0;
13733
13734 int32_t writesomedmaps(PACKFILE *f, int32_t first, int32_t last, int32_t max)
13735 {
13736
13737 dword section_version=V_DMAPS;
13738 int32_t zversion = ZELDA_VERSION;
13739 int32_t zbuild = VERSION_BUILD;
13740
13741 if(!p_iputl(V_ZDMAP,f))
13742 {
13743 return 0;
13744 }
13745
13746 //section version info
13747 if(!p_iputl(zversion,f))
13748 {
13749 return 0;
13750 }
13751 if(!p_iputl(zbuild,f))
13752 {
13753 return 0;
13754 }
13755 if(!p_iputw(section_version,f))
13756 {
13757 new_return(2);
13758 }
13759
13760 if(!write_deprecated_section_cversion(section_version, f))
13761 {
13762 new_return(3);
13763 }
13764 //max possible at this time
13765 if(!p_iputl(max,f))
13766 {
13767 new_return(4);
13768 }
13769 //first id written
13770 if(!p_iputl(first,f))
13771 {
13772 new_return(5);
13773 }
13774 //last id written
13775 if(!p_iputl(last,f))
13776 {
13777 new_return(6);
13778 }
13779 int32_t count = last-first;
13780 //number written
13781 if(!p_iputl(count,f))
13782 {
13783 new_return(7);
13784 }
13785
13786
13787 for ( int32_t i = first; i <= last; ++i )
13788 {
13789 if ( i > max ) break;
13790
13791 if (int ret = write_one_dmap(f, i))
13792 return ret;
13793 }
13794
13795 return 1;
13796 }
13797
13798 int32_t readsomedmaps(PACKFILE *f)
13799 {
13800 dword section_version = 0;
13801 int32_t zversion = 0;
13802 int32_t zbuild = 0;
13803 dmap tempdmap{};
13804
13805 int32_t first = 0, last = 0, max = 0, count = 0;
13806 int32_t datatype_version = 0;
13807
13808 //char dmapstring[64]={0};
13809 //section version info
13810 if(!p_igetl(&datatype_version,f))
13811 {
13812 return 0;
13813 }
13814 if ( datatype_version < 0 )
13815 {
13816 if(!p_igetl(&zversion,f))
13817 {
13818 return 0;
13819 }
13820 }
13821 else
13822 {
13823 zversion = datatype_version;
13824 }
13825 if(!p_igetl(&zbuild,f))
13826 {
13827 return 0;
13828 }
13829
13830 if(!p_igetw(&section_version,f))
13831 {
13832 return 0;
13833 }
13834
13835 if(!read_deprecated_section_cversion(f))
13836 {
13837 return 0;
13838 }
13839 if ( datatype_version < 0 )
13840 {
13841 if(!p_igetl(&max,f))
13842 {
13843 return 0;
13844 }
13845 if(!p_igetl(&first,f))
13846 {
13847 return 0;
13848 }
13849 if(!p_igetl(&last,f))
13850 {
13851 return 0;
13852 }
13853 if(!p_igetl(&count,f))
13854 {
13855 return 0;
13856 }
13857 }
13858 else
13859 {
13860 first = 0;
13861 last = 0;
13862 count = 1;
13863 max = 255;
13864 }
13865
13866
13867
13868
13869 al_trace("readsomedmaps section_version: %d\n", section_version);
13870
13871 if ( zversion > ZELDA_VERSION )
13872 {
13873 al_trace("Cannot read .zdmap packfile made in ZC version (%x) in this version of ZC (%x)\n", zversion, ZELDA_VERSION);
13874 return 0;
13875 }
13876 else if (( section_version > V_DMAPS ))
13877 {
13878 al_trace("Cannot read .zdmap packfile made using V_DMAPS (%d)\n", section_version);
13879 return 0;
13880 }
13881 else
13882 {
13883 al_trace("Reading a .zdmap packfile made in ZC Version: %x, Build: %d\n", zversion, zbuild);
13884 }
13885 //if(!pfread(&dmapstring, 64, f))
13886 //{
13887 // return 0;
13888 //}
13889 for ( int32_t i = first; i <= last; ++i )
13890 {
13891 if (int ret = read_one_dmap(f, &header, section_version, i))
13892 return ret;
13893 }
13894 return 1;
13895 }
13896
13897 int32_t onDmaps()
13898 {
13899 DMapListerDialog(0).show();
13900 return D_O_K;
13901 }
13902
13903 int32_t onMaps()
13904 {
13905 call_edit_map_settings(Map.getCurrMap());
13906 return D_O_K;
13907 }
13908
13909 int32_t onMusic()
13910 {
13911 stopMusic();
13912 call_music_dialog();
13913 return D_O_K;
13914 }
13915 int32_t onMidis()
13916 {
13917 stopMusic();
13918 MidiListerDialog().show();
13919 return D_O_K;
13920 }
13921
13922 const char *warptypelist(int32_t index, int32_t *list_size)
13923 {
13924 if(index>=0)
13925 {
13926 if(index>=MAXWARPTYPES)
13927 index=MAXWARPTYPES-1;
13928
13929 return warptype_string[index];
13930 }
13931
13932 *list_size=MAXWARPTYPES;
13933 // *list_size=6;
13934 return NULL;
13935 }
13936
13937 const char *warpeffectlist(int32_t index, int32_t *list_size)
13938 {
13939 if(index>=0)
13940 {
13941 if(index>=MAXWARPEFFECTS)
13942 index=MAXWARPEFFECTS-1;
13943
13944 return warpeffect_string[index];
13945 }
13946
13947 *list_size=MAXWARPEFFECTS;
13948 return NULL;
13949 }
13950
13951 static int32_t warp1_list[] =
13952 {
13953 2,3,4,5,6,7,8,9,10,11,12,13,53,54,63,67,-1
13954 };
13955
13956 static int32_t warp2_list[] =
13957 {
13958 17,18,19,20,21,22,23,24,25,26,27,28,55,56,64,68,-1
13959 };
13960
13961 static int32_t warp3_list[] =
13962 {
13963 29,30,31,32,33,34,35,36,37,38,39,40,57,58,65,69,-1
13964 };
13965
13966 static int32_t warp4_list[] =
13967 {
13968 41,42,43,44,45,46,47,48,49,50,51,52,59,60,66,70,-1
13969 };
13970
13971 static TABPANEL warp_tabs[] =
13972 {
13973 // (text)
13974 { (char *)"A", D_SELECTED, warp1_list, 0, NULL },
13975 { (char *)"B", 0, warp2_list, 0, NULL },
13976 { (char *)"C", 0, warp3_list, 0, NULL },
13977 { (char *)"D", 0, warp4_list, 0, NULL },
13978 { NULL, 0, NULL, 0, NULL }
13979 };
13980
13981 int32_t onTileWarpIndex(int32_t index)
13982 {
13983 int32_t i=-1;
13984
13985 while(warp_tabs[++i].text != NULL)
13986 warp_tabs[i].flags = (i==index ? D_SELECTED : 0);
13987
13988 onTileWarp();
13989 return D_O_K;
13990 }
13991
13992 static char warpr_buf[10];
13993 const char *warprlist(int32_t index, int32_t *list_size)
13994 {
13995 if(index>=0)
13996 {
13997 bound(index,0,3);
13998 sprintf(warpr_buf,"%c",index+0x41);
13999 return warpr_buf;
14000 }
14001
14002 *list_size=4;
14003 return NULL;
14004 }
14005
14006 int32_t d_wflag_proc(int32_t msg,DIALOG *d,int32_t c);
14007
14008 12 static ListData warp_dlg_list(warptypelist, &font);
14009 12 static ListData warp_ret_list(warprlist, &font);
14010
14011 int32_t d_warpdestscrsel_proc(int32_t msg,DIALOG *d,int32_t c)
14012 {
14013 if(msg == MSG_START)
14014 {
14015 d->d1 = -1; //cached val
14016 d->d2 = -1; //cached dmap
14017 d->fg = 0; //cached 'force_16'
14018 }
14019 char* buf = (char*)d->dp;
14020 vector<DIALOG*>* dlgs = (vector<DIALOG*>*)d->dp2;
14021 int* dmap_ptr = (int*) d->dp3;
14022 if(!(buf && dmap_ptr))
14023 return D_O_K;
14024 bool is_overworld = ((DMaps[*dmap_ptr].type&dmfTYPE)==dmOVERW);
14025 int scrw = is_overworld ? 16 : 8, scrh = 9;
14026 const int max = 0x87;
14027 int bufval = zc_xtoi(buf);
14028 int val = vbound(bufval,0,max);
14029 auto& dm = DMaps[*dmap_ptr];
14030 auto val_offset = dm.xoff < 0 ? -dm.xoff : 0;
14031 bool force_16 = d->fg;
14032 if(!is_overworld)
14033 {
14034 if((val&0xF) >= 0x8)
14035 force_16 = true;
14036 else if((val&0xF) < val_offset && (val&0xF0) < 0x80)
14037 force_16 = true;
14038 }
14039 if(force_16) //can't bound, some quests need to warp out of bounds... -Em
14040 {
14041 scrw = 16; //just force show the larger grid instead
14042 val_offset = 0;
14043 }
14044
14045 int xscl = d->w/scrw;
14046 int yscl = d->h/scrh;
14047
14048 int ret = D_O_K;
14049 bool redraw = false;
14050 if(d->d1 != val)
14051 {
14052 redraw = true;
14053 d->d1 = val;
14054 }
14055 if(bufval != val)
14056 {
14057 redraw = true;
14058 sprintf(buf, "%X", val);
14059 }
14060 if(d->d2 != *dmap_ptr)
14061 {
14062 redraw = true;
14063 d->d2 = *dmap_ptr;
14064 }
14065 switch(msg)
14066 {
14067 case MSG_WANTFOCUS:
14068 ret = D_WANTFOCUS;
14069 break;
14070 case MSG_CLICK:
14071 {
14072 d->fg = force_16 ? 1 : 0;
14073 bool redraw2 = false;
14074 while(gui_mouse_b())
14075 {
14076 if(redraw2)
14077 {
14078 broadcast_dialog_message(MSG_DRAW, 0);
14079 redraw2 = false;
14080 }
14081 if(!d->fg && (gui_mouse_b()&2))
14082 {
14083 scrw = 16;
14084 xscl = d->w/scrw;
14085 yscl = d->h/scrh;
14086 val_offset = 0;
14087 d->fg = 1;
14088 redraw2 = true;
14089 }
14090 custom_vsync();
14091 if(!mouse_in_rect(d->x,d->y,d->w,d->h))
14092 continue;
14093 int mx = gui_mouse_x()-d->x, my = gui_mouse_y()-d->y;
14094 int y = vbound(my/yscl,0,scrh-1);
14095 auto offs = y==8 ? 0 : val_offset;
14096 int x = vbound(mx/xscl,offs,scrw-1);
14097 auto val2 = (y*16)+x;
14098 if(val2 > max) //out of bounds in the bottom-right
14099 continue;
14100 val = val2;
14101 if(d->d1 != val)
14102 {
14103 d->d1 = val;
14104 sprintf(buf, "%02X", val);
14105 redraw2 = true;
14106 }
14107 }
14108 redraw = true;
14109 d->fg = 0;
14110 break;
14111 }
14112 case MSG_DRAW:
14113 {
14114 rectfill(screen,d->x,d->y,d->x+d->w-1,d->y+d->h-1,jwin_pal[jcBOX]);
14115 jwin_draw_frame(screen, d->x-2, d->y-2, d->w+4, d->h+4, FR_MENU);
14116 for(int yind = 0; yind < scrh; ++yind)
14117 {
14118 auto gr = (yind < 8 ? dm.grid[yind] : 0);
14119 for(int xind = (yind == 8 ? 0 : val_offset); xind < scrw; ++xind)
14120 {
14121 int screen_index = xind+(yind*16);
14122 if(screen_index > max)
14123 continue;
14124 int fr = FR_MENU;
14125 if(screen_index == d->d1)
14126 fr = FR_GREEN;
14127 else if(!is_overworld && xind < 8 && (gr&(1<<(8-xind-1))))
14128 fr = FR_MENU_INV;
14129 jwin_draw_frame(screen, d->x+(xind*xscl), d->y+(yind*yscl), xscl, yscl, fr);
14130 }
14131 }
14132 break;
14133 }
14134 case MSG_XCHAR:
14135 {
14136 bool on_80 = (val&0xF0) == 0x80;
14137 switch(c>>8)
14138 {
14139 case KEY_UP:
14140 if((val&0xF0) && !(val_offset && on_80 && (val&0xF) < val_offset))
14141 {
14142 val -= 0x10;
14143 redraw = true;
14144 }
14145 ret |= D_USED_CHAR;
14146 break;
14147 case KEY_DOWN:
14148 if((val&0xF0) < ((val&0xF) < 0x8 ? 0x80 : 0x70))
14149 {
14150 val += 0x10;
14151 redraw = true;
14152 }
14153 ret |= D_USED_CHAR;
14154 break;
14155 case KEY_LEFT:
14156 if((val&0xF) > (on_80 ? 0 : val_offset))
14157 {
14158 --val;
14159 redraw = true;
14160 }
14161 ret |= D_USED_CHAR;
14162 break;
14163 case KEY_RIGHT:
14164 if((val&0xF) < scrw-1 && val < 0x87)
14165 {
14166 ++val;
14167 redraw = true;
14168 }
14169 ret |= D_USED_CHAR;
14170 break;
14171 }
14172 if(redraw)
14173 sprintf(buf, "%02X", val);
14174 break;
14175 }
14176 }
14177 if(redraw)
14178 {
14179 if(msg == MSG_IDLE)
14180 broadcast_dialog_message(MSG_DRAW,0);
14181 else
14182 {
14183 d->d1 = d->d2 = -1;
14184 object_message(d,MSG_IDLE,0);
14185 }
14186 }
14187
14188 return ret;
14189 }
14190
14191 int32_t tilewarpdmapxy[6] = {170,38,170,18,170,27};
14192 static DIALOG tilewarp_dlg[] =
14193 {
14194 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
14195 12 { jwin_win_proc, 0, 0, 302, 178, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
14196 12 { jwin_rtext_proc, 89, 43, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Type:", NULL, NULL },
14197 12 { jwin_rtext_proc, 57, 62, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "DMap:", NULL, NULL },
14198 12 { jwin_rtext_proc, 57, 80, 64, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Screen: 0x", NULL, NULL },
14199 12 { jwin_droplist_proc, 91, 38, 193, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &warp_dlg_list, NULL, NULL },
14200 //5
14201 12 { d_dropdmaplist_proc, 59, 57, 225, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &dmap_list, NULL, tilewarpdmapxy },
14202 12 { jwin_hexedit_proc, 59, 76, 24, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
14203 12 { jwin_button_proc, 61, 152, 41, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
14204 12 { jwin_button_proc, 121, 152, 41, 21, vc(14), vc(1), 'g', D_EXIT, 0, 0, (void *) "&Go", NULL, NULL },
14205 12 { jwin_button_proc, 181, 152, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14206 //10
14207 12 { jwin_rtext_proc, 82, 95, 100, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Use Warp Return:", NULL, NULL },
14208 12 { jwin_droplist_proc, 10, 105, 72, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &warp_ret_list, NULL, NULL },
14209 12 { jwin_check_proc, 10, 125, 129, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Combos Carry Over", NULL, NULL },
14210 12 { d_warpdestscrsel_proc, 90, 76, 8*16, 8*9, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14211 12 { jwin_button_proc, 59, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "A", NULL, NULL },
14212 //15
14213 12 { jwin_button_proc, 109, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "B", NULL, NULL },
14214 12 { jwin_button_proc, 159, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "C", NULL, NULL },
14215 12 { jwin_button_proc, 209, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "D", NULL, NULL },
14216 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14217 };
14218
14219 int32_t sidewarpdmapxy[6] = {170,38,170,18,170,27};
14220 static DIALOG sidewarp_dlg[] =
14221 {
14222 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
14223 12 { jwin_win_proc, 0, 0, 302, 178, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
14224 12 { jwin_rtext_proc, 89, 43, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Type:", NULL, NULL },
14225 12 { jwin_rtext_proc, 57, 62, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "DMap:", NULL, NULL },
14226 12 { jwin_rtext_proc, 57, 80, 64, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Screen: 0x", NULL, NULL },
14227 12 { jwin_droplist_proc, 91, 38, 193, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &warp_dlg_list, NULL, NULL },
14228 //5
14229 12 { d_dropdmaplist_proc, 59, 57, 225, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &dmap_list, NULL, tilewarpdmapxy },
14230 12 { jwin_hexedit_proc, 59, 76, 24, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
14231 12 { jwin_button_proc, 61, 152, 41, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
14232 12 { jwin_button_proc, 121, 152, 41, 21, vc(14), vc(1), 'g', D_EXIT, 0, 0, (void *) "&Go", NULL, NULL },
14233 12 { jwin_button_proc, 181, 152, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14234 //10
14235 12 { jwin_rtext_proc, 82, 95, 100, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Use Warp Return:", NULL, NULL },
14236 12 { jwin_droplist_proc, 10, 105, 72, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &warp_ret_list, NULL, NULL },
14237 12 { jwin_check_proc, 10, 125, 129, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Combos Carry Over", NULL, NULL },
14238 12 { d_warpdestscrsel_proc, 90, 76, 8*16, 8*9, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14239 12 { jwin_button_proc, 59, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "A", NULL, NULL },
14240 //15
14241 12 { jwin_button_proc, 109, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "B", NULL, NULL },
14242 12 { jwin_button_proc, 159, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "C", NULL, NULL },
14243 12 { jwin_button_proc, 209, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "D", NULL, NULL },
14244 // 18
14245 12 { d_wflag_proc, 18, 17, 15, 8, vc(4), vc(0), 0, 0, 1, 0, NULL, NULL, NULL },
14246 12 { d_wflag_proc, 18, 47, 15, 8, vc(4), vc(0), 0, 0, 1, 0, NULL, NULL, NULL },
14247 // 20
14248 12 { d_wflag_proc, 8, 27, 8, 15, vc(4), vc(0), 0, 0, 1, 0, NULL, NULL, NULL },
14249 12 { d_wflag_proc, 37, 27, 8, 15, vc(4), vc(0), 0, 0, 1, 0, NULL, NULL, NULL },
14250
14251 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14252 };
14253
14254 int32_t warpringxy[6] = {170,38,170,18,170,27};
14255 static DIALOG warpring_warp_dlg[] =
14256 {
14257 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
14258 12 { jwin_win_proc, 0, 0, 302, 145, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
14259 12 { jwin_rtext_proc, 57, 25, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "DMap:", NULL, NULL },
14260 12 { jwin_rtext_proc, 57, 46, 64, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Screen: 0x", NULL, NULL },
14261 12 { d_dropdmaplist_proc, 59, 19, 225, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &dmap_list, NULL, warpringxy },
14262 12 { jwin_hexedit_proc, 59, 39, 24, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
14263 // 5
14264 12 { jwin_button_proc, 61, 115, 41, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
14265 12 { jwin_button_proc, 121, 115, 41, 21, vc(14), vc(1), 'g', D_EXIT, 0, 0, (void *) "&Go", NULL, NULL },
14266 12 { jwin_button_proc, 181, 115, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14267 12 { d_warpdestscrsel_proc, 90, 39, 8*16, 8*9, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14268
14269 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14270 };
14271
14272 // Side warp flag procedure
14273 int32_t d_wflag_proc(int32_t msg,DIALOG *d,int32_t)
14274 {
14275 int32_t ret = D_O_K;
14276 switch(msg)
14277 {
14278 case MSG_DRAW:
14279 {
14280 int32_t c2=(d->flags&D_SELECTED)?d->fg:d->bg;
14281
14282 if(d->d1==1)
14283 {
14284 jwin_draw_frame(screen,d->x,d->y,d->w,d->h, FR_DEEP);
14285 rectfill(screen,d->x+2, d->y+2, d->x+d->w-3, d->y+d->h-3,c2);
14286
14287 if(d->flags&D_SELECTED)
14288 {
14289 int32_t e=d->d2&3;
14290
14291 if(d->w>d->h)
14292 textprintf_centre_ex(screen,get_zc_font(font_lfont_l), d->x+(d->w/2),d->y,jwin_pal[jcBOXFG],-1,"%c",e+0x41);
14293 else
14294 textprintf_centre_ex(screen,get_zc_font(font_lfont_l), d->x+(d->w/2),d->y+(d->h/2)-4,jwin_pal[jcBOXFG],-1,"%c",e+0x41);
14295 }
14296
14297 }
14298 else
14299 {
14300 rectfill(screen,d->x, d->y, d->x+d->w-1, d->y+d->h-1,c2);
14301 }
14302 }
14303 break;
14304
14305 case MSG_CLICK:
14306 {
14307 if(d->flags & D_DISABLED)
14308 return D_O_K;
14309 bool rclick = gui_mouse_b() & 2;
14310 if(d->d1==1)
14311 {
14312 if(!(d->flags&D_SELECTED))
14313 {
14314 d->flags |= D_SELECTED;
14315 d->d2 &= 0x80;
14316 if (rclick)
14317 d->d2 |= 3;
14318 }
14319 else
14320 {
14321 if((d->d2&3) == (rclick?0:3))
14322 {
14323 d->flags ^= D_SELECTED;
14324 d->d2 &= 0x80;
14325 }
14326 else
14327 {
14328 int32_t f = d->d2&3;
14329 d->d2 &= 0x80;
14330 f += rclick ? -1 : 1;
14331 d->d2 |= f;
14332 }
14333 }
14334 }
14335 else
14336 {
14337 d->flags^=D_SELECTED;
14338 }
14339
14340 int32_t c2=(d->flags&D_SELECTED)?d->fg:d->bg;
14341
14342 if(d->d1==1)
14343 {
14344 jwin_draw_frame(screen,d->x,d->y,d->w,d->h, FR_DEEP);
14345 rectfill(screen,d->x+2, d->y+2, d->x+d->w-3, d->y+d->h-3,c2);
14346
14347 if(d->flags&D_SELECTED)
14348 {
14349 int32_t e=d->d2&3;
14350
14351 if(d->w>d->h)
14352 textprintf_centre_ex(screen,get_zc_font(font_lfont_l),d->x+(d->w/2),d->y,jwin_pal[jcBOXFG],-1,"%c",e+0x41);
14353 else
14354 textprintf_centre_ex(screen,get_zc_font(font_lfont_l),d->x+(d->w/2),d->y+(d->h/2)-4,jwin_pal[jcBOXFG],-1,"%c",e+0x41);
14355 }
14356 }
14357 else
14358 {
14359 rectfill(screen,d->x, d->y, d->x+d->w-1, d->y+d->h-1,c2);
14360 }
14361
14362
14363 while(gui_mouse_b())
14364 {
14365 /* do nothing */
14366 rest(1);
14367 }
14368 ret = D_REDRAWME;
14369 }
14370 break;
14371 }
14372
14373 return ret;
14374 }
14375
14376 int32_t d_dmapscrsel_proc(int32_t msg,DIALOG *d,int32_t c)
14377 {
14378 //these are here to bypass compiler warnings about unused arguments
14379 c=c;
14380
14381 int32_t ret = D_O_K;
14382
14383 switch(msg)
14384 {
14385 case MSG_CLICK:
14386 sprintf((char*)((d+2)->dp),"%X%X",vbound((gui_mouse_y()-d->y)/4,0,7),vbound((gui_mouse_x()-d->x)/(((DMaps[(d-1)->d1].type&dmfTYPE)==1)?4:8),0,(((DMaps[(d-1)->d1].type&dmfTYPE)==1)?15:7)));
14387 object_message(d+2, MSG_DRAW, 0);
14388 break;
14389 }
14390
14391 return ret;
14392 }
14393
14394 int32_t warpdestsel_x=-1;
14395 int32_t warpdestsel_y=-1;
14396 int32_t warpdestmap=-1;
14397 int32_t warpdestscr=-1;
14398
14399 int32_t jwin_minibutton_proc(int32_t msg,DIALOG *d,int32_t c)
14400 {
14401 switch(msg)
14402 {
14403 case MSG_DRAW:
14404 jwin_draw_text_button(screen, d->x, d->y, d->w, d->h, (char*)d->dp, d->flags, false);
14405 return D_O_K;
14406 break;
14407 }
14408
14409 return jwin_button_proc(msg,d,c);
14410 }
14411
14412 int32_t d_triggerbutton_proc(int32_t msg,DIALOG *d,int32_t c)
14413 {
14414 static BITMAP *dummy=create_bitmap_ex(8, 1, 1);
14415
14416 switch(msg)
14417 {
14418 case MSG_START:
14419 d->w=gui_textout_ln(dummy, font, (uint8_t *)d->dp, 0, 0, jwin_pal[jcMEDDARK], -1, 0)+4;
14420 d->h=text_height(font)+5;
14421 break;
14422
14423 case MSG_GOTFOCUS:
14424 d->flags&=~D_GOTFOCUS;
14425 break;
14426
14427 }
14428
14429 return jwin_minibutton_proc(msg,d,c);
14430 }
14431
14432 int32_t d_alltriggerbutton_proc(int32_t msg,DIALOG *d,int32_t c)
14433 {
14434 DIALOG *temp_d;
14435 int32_t ret=d_triggerbutton_proc(msg,d,c);
14436
14437 switch(msg)
14438 {
14439 case MSG_CLICK:
14440 temp_d=d-1;
14441
14442 while(temp_d->proc==d_triggerbutton_proc)
14443 {
14444 temp_d->flags&=~D_SELECTED;
14445 temp_d->flags|=D_DIRTY;
14446
14447 if(d->flags&D_SELECTED)
14448 {
14449 temp_d->flags|=D_SELECTED;
14450 }
14451
14452 --temp_d;
14453 }
14454
14455 break;
14456 }
14457
14458 return ret;
14459 }
14460
14461 int32_t d_ticsedit_proc(int32_t msg,DIALOG *d,int32_t c)
14462 {
14463 int32_t ret = jwin_edit_proc(msg,d,c);
14464
14465 if(msg==MSG_DRAW)
14466 {
14467 int32_t tics=vbound(atoi((char*)d->dp),0,65535);
14468 sprintf((char*)(d+1)->dp,"%s %s",ticksstr(tics),tics==0?"(No Timed Warp)":" ");
14469 object_message(d+1,MSG_DRAW,c);
14470 }
14471
14472 return ret;
14473 }
14474
14475 12 static ListData warp_effect_list(warpeffectlist,&font);
14476
14477 struct tw_data
14478 {
14479 int twscr[4], twtype[4], twdmap[4], wret[4];
14480 byte oflags;
14481 optional<uint> loaded;
14482
14483 tw_data(mapscr* scr) {load_scr(scr);}
14484 void load_scr(mapscr* scr)
14485 {
14486 oflags = scr->tilewarpoverlayflags;
14487 for(int q = 0; q < 4; ++q)
14488 {
14489 twscr[q] = scr->tilewarpscr[q];
14490 twtype[q] = scr->tilewarptype[q];
14491 twdmap[q] = scr->tilewarpdmap[q];
14492 wret[q] = (scr->warpreturnc >> (2*q))&3;
14493 }
14494 loaded.reset();
14495 }
14496 void save_scr(mapscr* scr)
14497 {
14498 mark_save_dirty();
14499 scr->tilewarpoverlayflags = oflags;
14500 scr->warpreturnc = scr->warpreturnc & 0xFF00;
14501 for(int q = 0; q < 4; ++q)
14502 {
14503 scr->tilewarpscr[q] = twscr[q];
14504 scr->tilewarptype[q] = twtype[q];
14505 scr->tilewarpdmap[q] = twdmap[q];
14506 scr->warpreturnc |= wret[q] << (2*q);
14507 }
14508 }
14509
14510 void load(uint ind)
14511 {
14512 if(ind >= 4) return;
14513 loaded = ind;
14514 tilewarp_dlg[4].d1 = twtype[ind];
14515 tilewarp_dlg[5].d1 = twdmap[ind];
14516 char* buf = (char*)tilewarp_dlg[6].dp;
14517 sprintf(buf,"%02X",twscr[ind]);
14518 tilewarp_dlg[11].d1 = wret[ind];
14519 SETFLAG(tilewarp_dlg[12].flags, D_SELECTED, get_bit(&oflags,ind));
14520 for(int q = 0; q < 4; ++q)
14521 SETFLAG(tilewarp_dlg[14+q].flags,(D_SELECTED|D_DISABLED),q==ind);
14522 }
14523 void save(uint ind)
14524 {
14525 if(ind >= 4) return;
14526 twtype[ind] = tilewarp_dlg[4].d1;
14527 twdmap[ind] = tilewarp_dlg[5].d1;
14528 char* buf = (char*)tilewarp_dlg[6].dp;
14529 twscr[ind] = vbound(zc_xtoi(buf),0x00,0x87);
14530 wret[ind] = tilewarp_dlg[11].d1;
14531 set_bit(&oflags, ind, tilewarp_dlg[12].flags & D_SELECTED);
14532 }
14533 void save()
14534 {
14535 if(loaded)
14536 save(*loaded);
14537 }
14538 void swap(uint ind)
14539 {
14540 if(ind >= 4) return;
14541 if(loaded)
14542 {
14543 save(*loaded);
14544 if(*loaded == ind)
14545 return;
14546 }
14547 load(ind);
14548 }
14549 };
14550 int32_t onTileWarp()
14551 {
14552 restore_mouse();
14553 tilewarp_dlg[0].dp=(void *) "Tile Warp";
14554 tilewarp_dlg[0].dp2=get_zc_font(font_lfont);
14555
14556 mapscr* mptr = Map.CurrScr();
14557 char buf[10];
14558 tilewarp_dlg[6].dp=buf;
14559 tilewarp_dlg[13].dp = buf;
14560 tilewarp_dlg[13].dp3 = &tilewarp_dlg[5].d1;
14561
14562 vector<DIALOG*> dlgs;
14563 dlgs.push_back(&tilewarp_dlg[5]);
14564 dlgs.push_back(&tilewarp_dlg[6]);
14565 tilewarp_dlg[13].dp2 = &dlgs;
14566
14567 tw_data data(mptr);
14568 data.load(0);
14569
14570 dmap_list_size=MAXDMAPS;
14571 dmap_list_zero=true;
14572
14573 large_dialog(tilewarp_dlg);
14574
14575 bool running = true;
14576 int ret;
14577 do
14578 {
14579 ret = do_zqdialog(tilewarp_dlg,-1);
14580 switch(ret)
14581 {
14582 // OK, GO
14583 case 7: case 8:
14584 running = false;
14585 data.save();
14586 data.save_scr(mptr);
14587 refresh(rMENU);
14588 break;
14589 //Cancel
14590 case 9:
14591 running = false;
14592 break;
14593 //A,B,C,D
14594 case 14: case 15: case 16: case 17:
14595 data.swap(ret-14);
14596 break;
14597 }
14598 }
14599 while(running);
14600
14601 if(ret==8) //GO
14602 {
14603 int32_t index = *data.loaded;
14604
14605 FlashWarpSquare = -1;
14606 int32_t tm = Map.getCurrMap();
14607 int32_t ts = Map.getCurrScr();
14608 int32_t thistype = mptr->tilewarptype[index];
14609 Map.dowarp(0,index);
14610
14611 if((ts!=Map.getCurrScr() || tm!=Map.getCurrMap()) && thistype != wtCAVE && thistype != wtSCROLL)
14612 {
14613 FlashWarpSquare = (TheMaps[tm*MAPSCRS+ts].warpreturnc>>(index*2))&3;
14614 FlashWarpClk = 32;
14615 }
14616
14617 refresh(rALL);
14618 }
14619
14620 return D_O_K;
14621 }
14622
14623 struct sw_data
14624 {
14625 int swscr[4], swtype[4], swdmap[4], wret[4];
14626 byte oflags;
14627 optional<uint> loaded;
14628
14629 sw_data(mapscr* scr) {load_scr(scr);}
14630 void load_scr(mapscr* scr)
14631 {
14632 oflags = scr->sidewarpoverlayflags;
14633 for(int q = 0; q < 4; ++q)
14634 {
14635 swscr[q] = scr->sidewarpscr[q];
14636 swtype[q] = scr->sidewarptype[q];
14637 swdmap[q] = scr->sidewarpdmap[q];
14638 wret[q] = (scr->warpreturnc >> (2*(q+4)))&3;
14639 }
14640 loaded.reset();
14641
14642 for(int32_t i=0; i<4; i++)
14643 {
14644 sidewarp_dlg[18+i].d2 = 0x80;
14645 if(scr->flags2&(1<<i))
14646 {
14647 sidewarp_dlg[18+i].flags = D_SELECTED ;
14648 sidewarp_dlg[18+i].d2 |= (scr->sidewarpindex>>(2*i))&3;
14649 }
14650 else
14651 {
14652 sidewarp_dlg[18+i].flags = 0;
14653 }
14654 }
14655 }
14656 void save_scr(mapscr* scr)
14657 {
14658 mark_save_dirty();
14659 scr->sidewarpoverlayflags = oflags;
14660 scr->warpreturnc = scr->warpreturnc & 0x00FF;
14661 for(int q = 0; q < 4; ++q)
14662 {
14663 scr->sidewarpscr[q] = swscr[q];
14664 scr->sidewarptype[q] = swtype[q];
14665 scr->sidewarpdmap[q] = swdmap[q];
14666 scr->warpreturnc |= wret[q] << (2*(q+4));
14667 }
14668
14669 scr->flags2 &= ~0xF;
14670 scr->sidewarpindex = 0;
14671 for(int32_t i=0; i<4; i++)
14672 {
14673 if(sidewarp_dlg[18+i].flags & D_SELECTED)
14674 scr->flags2 |= 1<<i;
14675 scr->sidewarpindex |= (sidewarp_dlg[18+i].d2&3) << (i*2);
14676 }
14677 }
14678
14679 void load(uint ind)
14680 {
14681 if(ind >= 4) return;
14682 loaded = ind;
14683 sidewarp_dlg[4].d1 = swtype[ind];
14684 sidewarp_dlg[5].d1 = swdmap[ind];
14685 char* buf = (char*)sidewarp_dlg[6].dp;
14686 sprintf(buf,"%02X",swscr[ind]);
14687 sidewarp_dlg[11].d1 = wret[ind];
14688 SETFLAG(sidewarp_dlg[12].flags, D_SELECTED, get_bit(&oflags,ind));
14689 for(int q = 0; q < 4; ++q)
14690 SETFLAG(sidewarp_dlg[14+q].flags,(D_SELECTED|D_DISABLED),q==ind);
14691 }
14692 void save(uint ind)
14693 {
14694 if(ind >= 4) return;
14695 swtype[ind] = sidewarp_dlg[4].d1;
14696 swdmap[ind] = sidewarp_dlg[5].d1;
14697 char* buf = (char*)sidewarp_dlg[6].dp;
14698 swscr[ind] = vbound(zc_xtoi(buf),0x00,0x87);
14699 wret[ind] = sidewarp_dlg[11].d1;
14700 set_bit(&oflags, ind, sidewarp_dlg[12].flags & D_SELECTED);
14701 }
14702 void save()
14703 {
14704 if(loaded)
14705 save(*loaded);
14706 }
14707 void swap(uint ind)
14708 {
14709 if(ind >= 4) return;
14710 if(loaded)
14711 {
14712 save(*loaded);
14713 if(*loaded == ind)
14714 return;
14715 }
14716 load(ind);
14717 }
14718 };
14719 int32_t onSideWarp()
14720 {
14721 restore_mouse();
14722 sidewarp_dlg[0].dp=(void *) "Side Warp";
14723 sidewarp_dlg[0].dp2=get_zc_font(font_lfont);
14724
14725 mapscr* mptr = Map.CurrScr();
14726 char buf[10];
14727 sidewarp_dlg[6].dp=buf;
14728 sidewarp_dlg[13].dp = buf;
14729 sidewarp_dlg[13].dp3 = &sidewarp_dlg[5].d1;
14730
14731 vector<DIALOG*> dlgs;
14732 dlgs.push_back(&sidewarp_dlg[5]);
14733 dlgs.push_back(&sidewarp_dlg[6]);
14734 sidewarp_dlg[13].dp2 = &dlgs;
14735
14736 sw_data data(mptr);
14737 data.load(0);
14738
14739 dmap_list_size=MAXDMAPS;
14740 dmap_list_zero=true;
14741
14742 large_dialog(sidewarp_dlg);
14743
14744 bool running = true;
14745 int ret;
14746 do
14747 {
14748 ret = do_zqdialog(sidewarp_dlg,-1);
14749 switch(ret)
14750 {
14751 // OK, GO
14752 case 7: case 8:
14753 running = false;
14754 data.save();
14755 data.save_scr(mptr);
14756 refresh(rMENU);
14757 break;
14758 //Cancel
14759 case 9:
14760 running = false;
14761 break;
14762 //A,B,C,D
14763 case 14: case 15: case 16: case 17:
14764 data.swap(ret-14);
14765 break;
14766 }
14767 }
14768 while(running);
14769
14770 if(ret==8) //GO
14771 {
14772 int32_t index = *data.loaded;
14773
14774 FlashWarpSquare = -1;
14775 int32_t tm = Map.getCurrMap();
14776 int32_t ts = Map.getCurrScr();
14777
14778 int32_t thistype = mptr->sidewarptype[index];
14779 Map.dowarp(1,index);
14780
14781 if((ts!=Map.getCurrScr() || tm!=Map.getCurrMap()) && thistype != wtSCROLL)
14782 {
14783 FlashWarpSquare = (TheMaps[tm*MAPSCRS+ts].warpreturnc>>(8+index*2))&3;
14784 FlashWarpClk = 0x20;
14785 }
14786
14787 refresh(rALL);
14788 }
14789
14790 return D_O_K;
14791 }
14792
14793
14794
14795 const char *dirlist(int32_t index, int32_t *list_size)
14796 {
14797 if(index>=0)
14798 {
14799 if(index>3)
14800 index=3;
14801
14802 return mazedirstr[index];
14803 }
14804
14805 *list_size=4;
14806 return NULL;
14807 }
14808
14809 12 static ListData path_dlg_list(dirlist, &font);
14810
14811 static const char *wipestr[] = {"None", "Circle", "Oval", "Triangle", "SMAS", "Fade Black"};
14812 // enum {bosCIRCLE=0, bosOVAL, bosTRIANGLE, bosSMAS, bosFADEBLACK, bosMAX};
14813 const char *wipelist(int32_t index, int32_t *list_size)
14814 {
14815 if(index>=0)
14816 {
14817 if(index>5)
14818 index=5;
14819
14820 return wipestr[index];
14821 }
14822
14823 *list_size=6;
14824 return NULL;
14825 }
14826
14827 12 static ListData wipe_effect_dlg_list(wipelist, &font);
14828
14829 static DIALOG path_dlg[] =
14830 {
14831 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
14832 12 { jwin_win_proc, 80, 57, 161, 182, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Maze Path", NULL, NULL },
14833 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14834 12 { jwin_text_proc, 94, 106, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "1st", NULL, NULL },
14835 12 { jwin_text_proc, 94, 124, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "2nd", NULL, NULL },
14836 12 { jwin_text_proc, 94, 142, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "3rd", NULL, NULL },
14837 12 { jwin_text_proc, 94, 160, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "4th", NULL, NULL },
14838 12 { jwin_text_proc, 94, 178, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Exit", NULL, NULL },
14839 12 { jwin_text_proc, 94, 196, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Wipe effect", NULL, NULL },
14840 12 { jwin_droplist_proc, 140, 102, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14841 12 { jwin_droplist_proc, 140, 120, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14842 12 { jwin_droplist_proc, 140, 138, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14843 12 { jwin_droplist_proc, 140, 156, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14844 12 { jwin_droplist_proc, 140, 174, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14845 12 { jwin_droplist_proc, 140, 192, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &wipe_effect_dlg_list, NULL, NULL },
14846 12 { jwin_button_proc, 90, 212, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
14847 12 { jwin_button_proc, 170, 212, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14848 12 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *) onHelp, NULL, NULL },
14849 12 { jwin_text_proc, 87, 82, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "A Lost Woods-style maze screen", NULL, NULL },
14850 12 { jwin_text_proc, 87, 92, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "with a normal and secret exit.", NULL, NULL },
14851 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14852 };
14853
14854 int32_t onPath()
14855 {
14856 restore_mouse();
14857 path_dlg[0].dp2=get_zc_font(font_lfont);
14858
14859 for(int32_t i=0; i<4; i++)
14860 path_dlg[i+8].d1 = Map.CurrScr()->path[i];
14861
14862 path_dlg[12].d1 = Map.CurrScr()->exitdir;
14863 path_dlg[13].d1 = Map.CurrScr()->maze_transition_wipe;
14864
14865 large_dialog(path_dlg);
14866
14867 int32_t ret;
14868
14869 do
14870 {
14871 ret=do_zqdialog(path_dlg,8);
14872
14873 if(ret==14)
14874 {
14875 for(int32_t i=0; i<4; i++)
14876 {
14877 if(path_dlg[i+8].d1 == path_dlg[12].d1)
14878 {
14879 if (alert_confirm("Exit Problem","One of the path's directions is also the normal Exit direction! Continue?"))
14880 ret = -1;
14881
14882 break;
14883 }
14884 }
14885 }
14886 }
14887 while(ret == -1);
14888
14889 if(ret==14)
14890 {
14891 mark_save_dirty();
14892
14893 for(int32_t i=0; i<4; i++)
14894 Map.CurrScr()->path[i] = path_dlg[i+8].d1;
14895
14896 Map.CurrScr()->exitdir = path_dlg[12].d1;
14897 Map.CurrScr()->maze_transition_wipe = path_dlg[13].d1;
14898
14899 if(!(Map.CurrScr()->flags&fMAZE))
14900 if (alert_confirm("Screen Flag","Turn on the 'Use Maze Path' Screen Flag?\n(Go to 'Screen Data' to turn it off.)"))
14901 Map.CurrScr()->flags |= fMAZE;
14902 }
14903
14904 refresh(rMAP+rMENU);
14905 return D_O_K;
14906 }
14907
14908
14909
14910 static DIALOG editinfo_dlg[] =
14911 {
14912 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
14913 12 { jwin_win_proc, 0, 10, 208, 204, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
14914 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14915 12 { jwin_text_proc, 24, 60, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "1st", NULL, NULL },
14916 12 { jwin_text_proc, 24, 106, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "2nd", NULL, NULL },
14917 12 { jwin_text_proc, 24, 152, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "3rd", NULL, NULL },
14918 12 { jwin_text_proc, 56, 60, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
14919 12 { jwin_text_proc, 56, 106, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
14920 12 { jwin_text_proc, 56, 152, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
14921 // 8
14922 12 { jwin_edit_proc, 86, 56, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
14923 12 { d_ndroplist_proc, 56, 74, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
14924 12 { jwin_edit_proc, 86, 102, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
14925 12 { d_ndroplist_proc, 56, 120, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
14926 12 { jwin_edit_proc, 86, 148, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
14927 12 { d_ndroplist_proc, 56, 166, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
14928 12 { jwin_text_proc, 24, 42, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Name:", NULL, NULL },
14929 12 { jwin_edit_proc, 56, 38, 137, 16, vc(12), vc(1), 0, 0, 31, 0, NULL, NULL, NULL },
14930 // 16
14931 12 { jwin_button_proc, 34, 188, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
14932 12 { jwin_button_proc, 114, 188, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14933 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14934 };
14935
14936 void EditInfoType(int32_t index)
14937 {
14938 char ps1[6],ps2[6],ps3[6];
14939 char infoname[33];
14940 char caption[40];
14941
14942 int32_t str1, str2, str3;
14943
14944 sprintf(caption,"Info Data %d",index);
14945 editinfo_dlg[0].dp = caption;
14946 editinfo_dlg[0].dp2 = get_zc_font(font_lfont);
14947
14948 sprintf(ps1,"%d",QMisc.info[index].price[0]);
14949 sprintf(ps2,"%d",QMisc.info[index].price[1]);
14950 sprintf(ps3,"%d",QMisc.info[index].price[2]);
14951 strncpy(infoname,QMisc.info[index].name,32);
14952 infoname[32] = 0;
14953 editinfo_dlg[8].dp = ps1;
14954 editinfo_dlg[10].dp = ps2;
14955 editinfo_dlg[12].dp = ps3;
14956 editinfo_dlg[15].dp = infoname;
14957 str1 = QMisc.info[index].str[0];
14958 str2 = QMisc.info[index].str[1];
14959 str3 = QMisc.info[index].str[2];
14960 editinfo_dlg[9].d1 = MsgStrings[str1].listpos;
14961 editinfo_dlg[11].d1 = MsgStrings[str2].listpos;
14962 editinfo_dlg[13].d1 = MsgStrings[str3].listpos;
14963 ListData msgs_list(msgslist2, &a4fonts[font_lfont_l]);
14964 editinfo_dlg[9].dp =
14965 editinfo_dlg[11].dp =
14966 editinfo_dlg[13].dp = (void *) &msgs_list;
14967
14968 large_dialog(editinfo_dlg);
14969
14970 int32_t ret = do_zqdialog(editinfo_dlg,-1);
14971
14972 if(ret==16)
14973 {
14974 mark_save_dirty();
14975 QMisc.info[index].price[0] = vbound(atoi(ps1), 0, 65535);
14976 QMisc.info[index].price[1] = vbound(atoi(ps2), 0, 65535);
14977 QMisc.info[index].price[2] = vbound(atoi(ps3), 0, 65535);
14978 strncpy(QMisc.info[index].name,infoname,32);
14979 str1 = editinfo_dlg[9].d1;
14980 str2 = editinfo_dlg[11].d1;
14981 str3 = editinfo_dlg[13].d1;
14982 QMisc.info[index].str[0] = msg_at_pos(str1);
14983 QMisc.info[index].str[1] = msg_at_pos(str2);
14984 QMisc.info[index].str[2] = msg_at_pos(str3);
14985
14986 //move 0s to the end
14987 word swaptmp;
14988
14989 if(QMisc.info[index].str[0] == 0)
14990 {
14991 //possibly permute the infos
14992 if(QMisc.info[index].str[1] != 0)
14993 {
14994 //swap
14995 swaptmp = QMisc.info[index].str[0];
14996 QMisc.info[index].str[0] = QMisc.info[index].str[1];
14997 QMisc.info[index].str[1] = swaptmp;
14998 swaptmp = QMisc.info[index].price[0];
14999 QMisc.info[index].price[0] = QMisc.info[index].price[1];
15000 QMisc.info[index].price[1] = swaptmp;
15001 }
15002 else if(QMisc.info[index].str[2] != 0)
15003 {
15004 //move info 0 to 1, 1 to 2, and 2 to 0
15005 swaptmp = QMisc.info[index].str[0];
15006 QMisc.info[index].str[0] = QMisc.info[index].str[2];
15007 QMisc.info[index].str[2] = QMisc.info[index].str[1];
15008 QMisc.info[index].str[1] = swaptmp;
15009 swaptmp = QMisc.info[index].price[0];
15010 QMisc.info[index].price[0] = QMisc.info[index].price[2];
15011 QMisc.info[index].price[2] = QMisc.info[index].price[1];
15012 QMisc.info[index].price[1] = swaptmp;
15013 }
15014 }
15015
15016 if(QMisc.info[index].str[1] == 0 && QMisc.info[index].str[2] != 0)
15017 //swap
15018 {
15019 swaptmp = QMisc.info[index].str[1];
15020 QMisc.info[index].str[1] = QMisc.info[index].str[2];
15021 QMisc.info[index].str[2] = swaptmp;
15022 swaptmp = QMisc.info[index].price[1];
15023 QMisc.info[index].price[1] = QMisc.info[index].price[2];
15024 QMisc.info[index].price[2] = swaptmp;
15025 }
15026 }
15027 }
15028
15029 int32_t onInfoTypes()
15030 {
15031 info_list_size = 256;
15032
15033 int32_t index = select_data("Info Types",0,infolist,"Edit","Done",get_zc_font(font_lfont));
15034
15035 while(index!=-1)
15036 {
15037 EditInfoType(index);
15038
15039 index = select_data("Info Types",index,infolist,"Edit","Done",get_zc_font(font_lfont));
15040 }
15041
15042 return D_O_K;
15043 }
15044
15045
15046
15047 //This dialogie is self-contained, and does not use dialogue control numbers in a separate array to generate its fields.
15048 static DIALOG editshop_dlg[] =
15049 {
15050 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
15051 12 { jwin_win_proc, 0, 10, 221, 204, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
15052 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
15053 12 { jwin_text_proc, 24, 60, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "1st", NULL, NULL },
15054 12 { jwin_text_proc, 24, 106, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "2nd", NULL, NULL },
15055 12 { jwin_text_proc, 24, 152, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "3rd", NULL, NULL },
15056 12 { jwin_text_proc, 56, 60, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
15057 12 { jwin_text_proc, 56, 106, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
15058 12 { jwin_text_proc, 56, 152, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
15059 // 8
15060 12 { jwin_edit_proc, 86, 56, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15061 12 { d_nidroplist_proc, 56, 74, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15062 12 { jwin_edit_proc, 86, 102, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15063 12 { d_nidroplist_proc, 56, 120, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15064 12 { jwin_edit_proc, 86, 148, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15065 12 { d_nidroplist_proc, 56, 166, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15066 12 { jwin_text_proc, 24, 42, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Name:", NULL, NULL },
15067 12 { jwin_edit_proc, 56, 38, 137, 16, vc(12), vc(1), 0, 0, 31, 0, NULL, NULL, NULL },
15068
15069 // 16
15070 12 { jwin_button_proc, 40, 188, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
15071 12 { jwin_button_proc, 121, 188, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
15072 //18
15073 12 { jwin_text_proc, 130, 60, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Info:", NULL, NULL },
15074 12 { jwin_text_proc, 130, 106, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Info:", NULL, NULL },
15075 12 { jwin_text_proc, 130, 152, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Info:", NULL, NULL },
15076 // 21
15077 12 { jwin_edit_proc, 155, 56, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15078 12 { jwin_edit_proc, 155, 102, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15079 12 { jwin_edit_proc, 155, 148, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15080
15081 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
15082 };
15083
15084 void EditShopType(int32_t index)
15085 {
15086
15087 build_bii_list(true);
15088 char ps1[6],ps2[6],ps3[6];
15089 char info1[6],info2[6],info3[6];
15090 char shopname[32];
15091 char caption[40];
15092
15093 sprintf(caption,"Shop Data %d",index);
15094 editshop_dlg[0].dp = caption;
15095 editshop_dlg[0].dp2=get_zc_font(font_lfont);
15096
15097 sprintf(ps1,"%d",QMisc.shop[index].price[0]);
15098 sprintf(ps2,"%d",QMisc.shop[index].price[1]);
15099 sprintf(ps3,"%d",QMisc.shop[index].price[2]);
15100
15101 sprintf(info1,"%d",QMisc.shop[index].str[0]);
15102 sprintf(info2,"%d",QMisc.shop[index].str[1]);
15103 sprintf(info3,"%d",QMisc.shop[index].str[2]);
15104
15105 sprintf(shopname,"%s",QMisc.shop[index].name);
15106 editshop_dlg[8].dp = ps1;
15107 editshop_dlg[10].dp = ps2;
15108 editshop_dlg[12].dp = ps3;
15109 editshop_dlg[15].dp = shopname;
15110
15111 editshop_dlg[21].dp = info1;
15112 editshop_dlg[22].dp = info2;
15113 editshop_dlg[23].dp = info3;
15114
15115 ListData item_list(itemlist_num, &a4fonts[font_lfont_l]);
15116
15117 editshop_dlg[9].dp = (void *) &item_list;
15118 editshop_dlg[11].dp = (void *) &item_list;
15119 editshop_dlg[13].dp = (void *) &item_list;
15120
15121 for(int32_t i=0; i<3; ++i)
15122 {
15123 if(QMisc.shop[index].hasitem[i])
15124 {
15125 for(int32_t j=0; j<bii_cnt; j++)
15126 {
15127 if(bii[j].i == QMisc.shop[index].item[i])
15128 {
15129 editshop_dlg[9+(i<<1)].d1 = j;
15130 }
15131 }
15132 }
15133 else
15134 {
15135 editshop_dlg[9+(i<<1)].d1 = -2;
15136 }
15137 }
15138
15139 large_dialog(editshop_dlg);
15140
15141 int32_t ret = do_zqdialog(editshop_dlg,-1);
15142
15143 if(ret==16)
15144 {
15145 mark_save_dirty();
15146 QMisc.shop[index].price[0] = vbound(atoi(ps1), 0, 65535);
15147 QMisc.shop[index].price[1] = vbound(atoi(ps2), 0, 65535);
15148 QMisc.shop[index].price[2] = vbound(atoi(ps3), 0, 65535);
15149
15150 QMisc.shop[index].str[0] = vbound(atoi(info1), 0, 65535);
15151 QMisc.shop[index].str[1] = vbound(atoi(info2), 0, 65535);
15152 QMisc.shop[index].str[2] = vbound(atoi(info3), 0, 65535);
15153
15154 snprintf(QMisc.shop[index].name, 32, "%s",shopname);
15155
15156 for(int32_t i=0; i<3; ++i)
15157 {
15158 if(bii[editshop_dlg[9+(i<<1)].d1].i == -2)
15159 {
15160 QMisc.shop[index].hasitem[i] = 0;
15161 QMisc.shop[index].item[i] = 0;
15162 QMisc.shop[index].price[i] = 0;
15163 }
15164 else
15165 {
15166 QMisc.shop[index].hasitem[i] = 1;
15167 QMisc.shop[index].item[i] = bii[editshop_dlg[9+(i<<1)].d1].i;
15168 }
15169 }
15170
15171 //filter all the 0 items to the end (yeah, bubble sort; sue me)
15172 word swaptmp;
15173
15174 for(int32_t j=0; j<3-1; j++)
15175 {
15176 for(int32_t k=0; k<2-j; k++)
15177 {
15178 if(QMisc.shop[index].hasitem[k]==0)
15179 {
15180 swaptmp = QMisc.shop[index].item[k];
15181 QMisc.shop[index].item[k] = QMisc.shop[index].item[k+1];
15182 QMisc.shop[index].item[k+1] = swaptmp;
15183 swaptmp = QMisc.shop[index].price[k];
15184 QMisc.shop[index].price[k] = QMisc.shop[index].price[k+1];
15185 QMisc.shop[index].price[k+1] = swaptmp;
15186 swaptmp = QMisc.shop[index].hasitem[k];
15187 QMisc.shop[index].hasitem[k] = QMisc.shop[index].item[k+1];
15188 QMisc.shop[index].hasitem[k+1] = swaptmp;
15189 }
15190 }
15191 }
15192 }
15193 }
15194
15195 int32_t onShopTypes()
15196 {
15197 shop_list_size = 256;
15198
15199 int32_t index = select_data("Shop Types",0,shoplist,"Edit","Done",get_zc_font(font_lfont));
15200
15201 while(index!=-1)
15202 {
15203 EditShopType(index);
15204 index = select_data("Shop Types",index,shoplist,"Edit","Done",get_zc_font(font_lfont));
15205 }
15206
15207 return D_O_K;
15208 }
15209
15210 void call_bottle_dlg(int32_t index);
15211 int32_t onBottleTypes()
15212 {
15213 bottle_list_size = 64;
15214 int32_t index = 0;
15215
15216 while(index > -1)
15217 {
15218 index = select_data("Bottle Types", index, bottlelist, "Edit", "Done", get_zc_font(font_lfont));
15219 if(index > -1)
15220 call_bottle_dlg(index);
15221 }
15222
15223 return D_O_K;
15224 }
15225
15226 void call_bottleshop_dlg(int32_t index);
15227 int32_t onBottleShopTypes()
15228 {
15229 bottleshop_list_size = 256;
15230 int32_t index = 0;
15231
15232 while(index > -1)
15233 {
15234 index = select_data("Bottle Shop Types", index, bottleshoplist, "Edit", "Done", get_zc_font(font_lfont));
15235 if(index > -1)
15236 call_bottleshop_dlg(index);
15237 }
15238
15239 return D_O_K;
15240 }
15241
15242 int32_t onSaveMenus()
15243 {
15244 SaveMenuListerDialog().show();
15245 return D_O_K;
15246 }
15247
15248
15249 static char item_drop_set_str_buf[70];
15250 int32_t item_drop_set_list_size=MAXITEMDROPSETS;
15251
15252 const char *itemdropsetlist(int32_t index, int32_t *list_size)
15253 {
15254 if(index>=0)
15255 {
15256 bound(index,0,item_drop_set_list_size-1);
15257 sprintf(item_drop_set_str_buf,"%3d: %s",index,item_drop_sets[index].name);
15258 return item_drop_set_str_buf;
15259 }
15260
15261 *list_size=item_drop_set_list_size;
15262 return NULL;
15263 }
15264
15265 int32_t d_itemdropedit_proc(int32_t msg,DIALOG *d,int32_t c);
15266
15267 static int32_t edititemdropset_1_list[] =
15268 {
15269 // dialog control number
15270 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,24,25,26,27,28, -1
15271 };
15272
15273 static int32_t edititemdropset_2_list[] =
15274 {
15275 // dialog control number
15276 12, 13, 29, 30, 31, 32, 33,34,35,36,37,38,39,40,41,42,43, -1
15277 };
15278
15279 static TABPANEL edititemdropset_tabs[] =
15280 {
15281 // (text)
15282 { (char *)" Page 1 ", D_SELECTED, edititemdropset_1_list, 0, NULL },
15283 { (char *)" Page 2 ", 0, edititemdropset_2_list, 0, NULL },
15284 { NULL, 0, NULL, 0, NULL }
15285 };
15286
15287 static DIALOG edititemdropset_dlg[] =
15288 {
15289 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
15290 12 { jwin_win_proc, 0, 0, 320, 240, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
15291 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
15292
15293 // 2
15294 12 { jwin_button_proc, 89, 213, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
15295 12 { jwin_button_proc, 169, 213, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
15296
15297 // 4
15298 12 { jwin_text_proc, 9, 29, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Name:", NULL, NULL },
15299 12 { jwin_edit_proc, 39, 25, 275, 16, vc(12), vc(1), 0, 0, 32, 0, NULL, NULL, NULL },
15300 12 { jwin_text_proc, 9, 47, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Nothing Chance:", NULL, NULL },
15301 12 { d_itemdropedit_proc, 84, 43, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15302
15303 12 { jwin_tab_proc, 4, 65, 312, 143, vc(0), vc(15), 0, 0, 0, 0, (void *) edititemdropset_tabs, NULL, (void *)edititemdropset_dlg },
15304 12 { jwin_text_proc, 114, 43+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15305 // 10
15306 12 { jwin_text_proc, 10, 87, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Chance:", NULL, NULL },
15307 12 { jwin_text_proc, 56, 87, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Item:", NULL, NULL },
15308 12 { jwin_text_proc, 10, 87, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Chance:", NULL, NULL },
15309 12 { jwin_text_proc, 56, 87, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Item:", NULL, NULL },
15310
15311 // 14
15312 12 { d_itemdropedit_proc, 9, 96, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15313 12 { d_idroplist_proc, 55, 96, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15314 12 { jwin_text_proc, 37, 96+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15315 12 { d_itemdropedit_proc, 9, 118, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15316 12 { d_idroplist_proc, 55, 118, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15317 12 { jwin_text_proc, 37, 118+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15318 12 { d_itemdropedit_proc, 9, 140, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15319 12 { d_idroplist_proc, 55, 140, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15320 12 { jwin_text_proc, 37, 140+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15321 12 { d_itemdropedit_proc, 9, 162, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15322 12 { d_idroplist_proc, 55, 162, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15323 12 { jwin_text_proc, 37, 162+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15324 12 { d_itemdropedit_proc, 9, 184, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15325 12 { d_idroplist_proc, 55, 184, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15326 12 { jwin_text_proc, 37, 184+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15327 // 29
15328 12 { d_itemdropedit_proc, 9, 96, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15329 12 { d_idroplist_proc, 55, 96, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15330 12 { jwin_text_proc, 37, 96+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15331 12 { d_itemdropedit_proc, 9, 118, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15332 12 { d_idroplist_proc, 55, 118, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15333 12 { jwin_text_proc, 37, 118+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15334 12 { d_itemdropedit_proc, 9, 140, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15335 12 { d_idroplist_proc, 55, 140, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15336 12 { jwin_text_proc, 37, 140+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15337 12 { d_itemdropedit_proc, 9, 162, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15338 12 { d_idroplist_proc, 55, 162, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15339 12 { jwin_text_proc, 37, 162+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15340 12 { d_itemdropedit_proc, 9, 184, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15341 12 { d_idroplist_proc, 55, 184, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15342 12 { jwin_text_proc, 39, 184+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15343 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
15344 };
15345
15346 int32_t d_itemdropedit_proc(int32_t msg,DIALOG *d,int32_t c)
15347 {
15348 int32_t ret = jwin_edit_proc(msg,d,c);
15349
15350 if(msg==MSG_DRAW)
15351 {
15352 int32_t t = atoi((char*)edititemdropset_dlg[7].dp);
15353
15354 for(int32_t i=0; i<10; ++i)
15355 {
15356 t += atoi((char*)edititemdropset_dlg[14+(i*3)].dp);
15357 }
15358
15359 {
15360 int32_t t2 = (int32_t)(100*atoi((char*)edititemdropset_dlg[7].dp) / zc_max(t,1));
15361 sprintf((char*)edititemdropset_dlg[9].dp,"%d%%%s",t2, t2 <= 11 ? " ":"");
15362 object_message(&edititemdropset_dlg[9],MSG_DRAW,c);
15363 }
15364
15365 for(int32_t i=0; i<10; ++i)
15366 {
15367 int32_t t2 = (int32_t)(100*atoi((char*)edititemdropset_dlg[14+(i*3)].dp) / zc_max(t,1));
15368 sprintf((char*)edititemdropset_dlg[16+(i*3)].dp,"%d%%%s",t2, t2 <= 11 ? " ":"");
15369 object_message(&edititemdropset_dlg[16+(i*3)],MSG_DRAW,c);
15370 }
15371
15372 }
15373
15374 return ret;
15375 }
15376
15377 void EditItemDropSet(int32_t index)
15378 {
15379 build_bii_list(true);
15380 char chance[11][10];
15381 char itemdropsetname[64];
15382 char caption[40];
15383 char percent_str[11][5];
15384
15385 sprintf(caption,"Item Drop Set Data %d",index);
15386 edititemdropset_dlg[0].dp = caption;
15387 edititemdropset_dlg[0].dp2=get_zc_font(font_lfont);
15388
15389 sprintf(itemdropsetname,"%s",item_drop_sets[index].name);
15390 edititemdropset_dlg[5].dp = itemdropsetname;
15391
15392 sprintf(chance[0],"%d",item_drop_sets[index].chance[0]);
15393 edititemdropset_dlg[7].dp = chance[0];
15394
15395 ListData item_list(itemlist_num, &a4fonts[font_lfont_l]);
15396 sprintf(percent_str[0]," ");
15397 edititemdropset_dlg[9].dp = percent_str[0];
15398
15399 for(int32_t i=0; i<10; ++i)
15400 {
15401 sprintf(chance[i+1],"%d",item_drop_sets[index].chance[i+1]);
15402 edititemdropset_dlg[14+(i*3)].dp = chance[i+1];
15403 edititemdropset_dlg[15+(i*3)].dp = (void *) &item_list;
15404 sprintf(percent_str[i+1]," ");
15405 edititemdropset_dlg[16+(i*3)].dp = percent_str[i+1];
15406
15407 if(item_drop_sets[index].chance[i+1]==0)
15408 {
15409 edititemdropset_dlg[15+(i*3)].d1 = -2;
15410 }
15411 else
15412 {
15413 for(int32_t j=0; j<bii_cnt; j++)
15414 {
15415 if(bii[j].i == item_drop_sets[index].item[i])
15416 {
15417 edititemdropset_dlg[15+(i*3)].d1 = j;
15418 }
15419 }
15420 }
15421 }
15422
15423 large_dialog(edititemdropset_dlg);
15424
15425 int32_t ret = do_zqdialog(edititemdropset_dlg,-1);
15426
15427 if(ret==2)
15428 {
15429 mark_save_dirty();
15430
15431 sprintf(item_drop_sets[index].name,"%s",itemdropsetname);
15432
15433 item_drop_sets[index].chance[0]=atoi(chance[0]);
15434
15435 for(int32_t i=0; i<10; ++i)
15436 {
15437 item_drop_sets[index].chance[i+1]=atoi(chance[i+1]);
15438
15439 if(bii[edititemdropset_dlg[15+(i*3)].d1].i == -2)
15440 {
15441 item_drop_sets[index].chance[i+1]=0;
15442 }
15443 else
15444 {
15445 item_drop_sets[index].item[i] = bii[edititemdropset_dlg[15+(i*3)].d1].i;
15446 }
15447
15448 if(item_drop_sets[index].chance[i+1]==0)
15449 {
15450 item_drop_sets[index].item[i] = 0;
15451 }
15452 }
15453 }
15454 }
15455
15456 9 int32_t count_item_drop_sets()
15457 {
15458 9 int32_t count=0;
15459 9 bool found=false;
15460
15461
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2195 times.
2195 for(count=255; (count>0); --count)
15462 {
15463
2/2
✓ Branch 0 taken 2186 times.
✓ Branch 1 taken 24056 times.
26242 for(int32_t i=0; (i<11); ++i)
15464 {
15465
2/2
✓ Branch 0 taken 24047 times.
✓ Branch 1 taken 9 times.
24056 if(item_drop_sets[count].chance[i]!=0)
15466 {
15467 9 found=true;
15468 9 break;
15469 }
15470 24047 }
15471
15472
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2186 times.
2195 if(found)
15473 {
15474 9 break;
15475 }
15476 2186 }
15477
15478 9 return count+1;
15479 }
15480
15481 int32_t onItemDropSets()
15482 {
15483 item_drop_set_list_size = MAXITEMDROPSETS;
15484
15485 int32_t index = select_data("Item Drop Sets",0,itemdropsetlist,"Edit","Done",get_zc_font(font_lfont));
15486
15487 while(index!=-1)
15488 {
15489 EditItemDropSet(index);
15490 index = select_data("Item Drop Sets",index,itemdropsetlist,"Edit","Done",get_zc_font(font_lfont));
15491 }
15492
15493 return D_O_K;
15494 }
15495
15496 int32_t curr_ring = 0;
15497
15498 void EditWarpRingScr(int32_t ring,int32_t index)
15499 {
15500 char caption[40],buf[10];
15501 restore_mouse();
15502
15503 sprintf(caption,"Ring %d Warp %d",ring,index+1);
15504 warpring_warp_dlg[0].dp = (void *)caption;
15505 warpring_warp_dlg[0].dp2=get_zc_font(font_lfont);
15506
15507 sprintf(buf,"%02X",QMisc.warp[ring].scr[index]);
15508 warpring_warp_dlg[3].d1 = QMisc.warp[ring].dmap[index];
15509 warpring_warp_dlg[4].dp = buf;
15510 warpring_warp_dlg[8].dp = buf;
15511 warpring_warp_dlg[8].dp3 = &warpring_warp_dlg[3].d1;
15512
15513 vector<DIALOG*> dlgs;
15514 dlgs.push_back(&warpring_warp_dlg[3]);
15515 dlgs.push_back(&warpring_warp_dlg[4]);
15516 warpring_warp_dlg[8].dp2 = &dlgs;
15517
15518 dmap_list_size=MAXDMAPS;
15519 dmap_list_zero=true;
15520
15521 large_dialog(warpring_warp_dlg);
15522
15523 int32_t ret=do_zqdialog(warpring_warp_dlg,-1);
15524
15525 if(ret==5 || ret==6)
15526 {
15527 mark_save_dirty();
15528 QMisc.warp[ring].dmap[index] = warpring_warp_dlg[3].d1;
15529 QMisc.warp[ring].scr[index] = zc_xtoi(buf);
15530 }
15531
15532 if(ret==6)
15533 {
15534 Map.dowarp2(ring,index);
15535 refresh(rALL);
15536 }
15537 }
15538
15539 int32_t d_warplist_proc(int32_t msg,DIALOG *d,int32_t c)
15540 {
15541 if(msg==MSG_DRAW)
15542 {
15543 int32_t *xy = (int32_t*)(d->dp3);
15544 int32_t ring = curr_ring;
15545 int32_t dmap = QMisc.warp[ring].dmap[d->d1];
15546 float temp_scale = 1.5;
15547
15548 drawdmap(dmap);
15549
15550 if(xy[0]||xy[1])
15551 {
15552 int32_t x = d->x+int32_t((xy[0]-2)*temp_scale);
15553 int32_t y = d->y+int32_t((xy[1]-2)*temp_scale);
15554 int32_t w = 84;
15555 int32_t h = 52;
15556 jwin_draw_frame(screen,x,y,w,h,FR_DEEP);
15557 drawdmap_screen(x+2,y+2,w-4,h-4,dmap);
15558 }
15559
15560 if(xy[2]||xy[3])
15561 {
15562 textprintf_ex(screen,font,d->x+int32_t(xy[2]*temp_scale),d->y+int32_t(xy[3]*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Map: %d ",DMaps[dmap].map+1);
15563 }
15564
15565 if(xy[4]||xy[5])
15566 {
15567 textprintf_ex(screen,font,d->x+int32_t(xy[4]*temp_scale),d->y+int32_t(xy[5]*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Level:%2d ",DMaps[dmap].level);
15568 }
15569
15570 if(xy[6]||xy[7])
15571 {
15572 textprintf_ex(screen,font,d->x+int32_t(xy[6]*temp_scale),d->y+int32_t(xy[7]*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Scr: 0x%02X ",QMisc.warp[ring].scr[d->d1]);
15573 }
15574 }
15575
15576 return jwin_list_proc(msg,d,c);
15577 }
15578
15579 int32_t d_wclist_proc(int32_t msg,DIALOG *d,int32_t c)
15580 {
15581 int32_t d1 = d->d1;
15582 int32_t ret = jwin_droplist_proc(msg,d,c);
15583 QMisc.warp[curr_ring].size=d->d1+3;
15584
15585 if(d->d1 != d1)
15586 return D_CLOSE;
15587
15588 return ret;
15589 }
15590
15591 const char *wclist(int32_t index, int32_t *list_size)
15592 {
15593 static char buf[2];
15594
15595 if(index>=0)
15596 {
15597 if(index>6)
15598 index=6;
15599
15600 sprintf(buf,"%d",index+3);
15601 return buf;
15602 }
15603
15604 *list_size=7;
15605 return NULL;
15606 }
15607
15608 //int32_t warpringdmapxy[8] = {160,116,160,90,160,102,160,154};
15609 int32_t warpringdmapxy[8] = {80,26,80,0,80,12,80,78};
15610
15611 12 static ListData number_list(numberlist, &font);
15612 12 static ListData wc_list(wclist, &font);
15613
15614 static DIALOG warpring_dlg[] =
15615 {
15616 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
15617 12 { jwin_win_proc, 0, 0, 193, 166, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
15618 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
15619 12 { jwin_text_proc, 16, 33, 48, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Count:", NULL, NULL },
15620 12 { d_wclist_proc, 72, 29, 48, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 1, 0, (void *) &wc_list, NULL, NULL },
15621 // 4
15622 12 { d_warplist_proc, 16, 50, 65, 71, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, (void *) &number_list, NULL, warpringdmapxy },
15623 12 { jwin_button_proc, 26, 140, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Edit", NULL, NULL },
15624 12 { jwin_button_proc, 106, 140, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Done", NULL, NULL },
15625 12 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *) onHelp, NULL, NULL },
15626 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
15627 };
15628
15629 int32_t select_warp()
15630 {
15631 QMisc.warp[curr_ring].size = vbound(QMisc.warp[curr_ring].size,3,9);
15632 number_list_zero = false;
15633
15634 int32_t ret=4;
15635
15636 large_dialog(warpring_dlg);
15637
15638 do
15639 {
15640 number_list_size = QMisc.warp[curr_ring].size;
15641 warpring_dlg[3].d1 = QMisc.warp[curr_ring].size-3;
15642 ret = do_zqdialog(warpring_dlg,ret);
15643 }
15644 while(ret==3);
15645
15646 if(ret==6 || ret==0)
15647 {
15648 return -1;
15649 }
15650
15651 return warpring_dlg[4].d1;
15652 }
15653
15654 void EditWarpRing(int32_t ring)
15655 {
15656 char buf[40];
15657 sprintf(buf,"Ring %d Warps",ring);
15658 warpring_dlg[0].dp = buf;
15659 warpring_dlg[0].dp2 = get_zc_font(font_lfont);
15660 curr_ring = ring;
15661
15662 int32_t index = select_warp();
15663
15664 while(index!=-1)
15665 {
15666 EditWarpRingScr(ring,index);
15667 index = select_warp();
15668 }
15669 }
15670
15671 int32_t onWarpRings()
15672 {
15673 number_list_size = 9;
15674 number_list_zero = true;
15675
15676 int32_t index = select_data("Warp Rings",0,numberlist,"Edit","Done",get_zc_font(font_lfont));
15677
15678 while(index!=-1)
15679 {
15680 EditWarpRing(index);
15681 number_list_size = 9;
15682 number_list_zero = true;
15683 index = select_data("Warp Rings",index,numberlist,"Edit","Done",get_zc_font(font_lfont));
15684 }
15685
15686 return D_O_K;
15687 }
15688
15689 enemy_struct bie[eMAXGUYS];
15690 enemy_struct ce[100];
15691 int32_t enemy_type=0,bie_cnt=-1,ce_cnt;
15692
15693 //Uses old_max_guys[] in zq_misc.cpp to define what are visible if bool hide is set true. -Z
15694 void build_bie_list(bool hide)
15695 {
15696 bie[0].s = (char *)"(None)";
15697 bie[0].i = 0;
15698 bie_cnt=1;
15699
15700 for(int32_t i=1; i<eMAXGUYS; i++)
15701 {
15702 if (i < eSTART) continue; // ignore guys - enemies only!
15703
15704 if(i >= OLDMAXGUYS || old_guy_string[i][strlen(old_guy_string[i])-1]!=' ' || !hide)
15705 {
15706 bie[bie_cnt].s = (char *)guy_string[i];
15707 bie[bie_cnt].i = i;
15708 ++bie_cnt;
15709 }
15710 }
15711
15712 for(int32_t i=1; i<bie_cnt-1; i++) //Start at 1 so '(None)' isn't alphabetized!
15713 {
15714 for(int32_t j=i+1; j<bie_cnt; j++)
15715 {
15716 if(strcmp(bie[i].s,bie[j].s)>0)
15717 {
15718 zc_swap(bie[i],bie[j]);
15719 }
15720 }
15721 }
15722 }
15723
15724 int32_t efrontfacingtile(int32_t id)
15725 {
15726 int32_t anim = get_qr(qr_NEWENEMYTILES)?guysbuf[id].e_anim:guysbuf[id].anim;
15727 int32_t usetile = 0;
15728
15729 switch(anim)
15730 {
15731
15732 case aNONE: break;
15733 case aAQUA:
15734 if(!(get_qr(qr_NEWENEMYTILES) && guysbuf[id].attributes[0]))
15735 break;
15736
15737 case aWALLM:
15738 case aGHOMA:
15739 usetile=1;
15740 break;
15741
15742 //Fallthrough
15743 case a2FRM4DIR:
15744 case aWALK:
15745 usetile=2;
15746 break;
15747
15748 case aLEV:
15749 case a3FRM4DIR:
15750 usetile=3;
15751 break;
15752
15753 case aLANM:
15754 usetile = !(get_qr(qr_NEWENEMYTILES))?0:4;
15755 break;
15756
15757 case aNEWDONGO:
15758 case a4FRM8EYE:
15759 case aNEWWIZZ:
15760 case aARMOS4:
15761 case aNEWTEK:
15762 case aNEWWALLM:
15763 case a4FRM4DIRF:
15764 case a4FRM4DIR:
15765 case a4FRM8DIRF:
15766 case a4FRMPOS8DIR:
15767 case a4FRMPOS8DIRF:
15768 case a4FRMPOS4DIR:
15769 case a4FRMPOS4DIRF:
15770 usetile=4;
15771 break;
15772
15773 case aDONGO:
15774 usetile=6;
15775 break;
15776
15777 case aDONGOBS:
15778 usetile=24;
15779 break;
15780
15781 case aNEWLEV:
15782 usetile=40;
15783 break;
15784
15785 case aNEWZORA:
15786 if(guysbuf[id].type==eeZORA)
15787 usetile=44;
15788
15789 break;
15790
15791 case aGLEEOK:
15792 if(!get_qr(qr_NEWENEMYTILES))
15793 usetile = (guysbuf[id].s_tile - guysbuf[id].tile)+1;
15794 else
15795 usetile = (guysbuf[id].attributes[7]);
15796
15797 break;
15798 }
15799
15800 return zc_max(get_qr(qr_NEWENEMYTILES) ? -guysbuf[id].e_tile
15801 : -guysbuf[id].tile, usetile);
15802 }
15803
15804 int32_t onEnemies()
15805 {
15806 call_screenenemies_dialog();
15807 refresh(rALL);
15808 return D_O_K;
15809 }
15810
15811 int32_t onHeader()
15812 {
15813 call_header_dlg();
15814 return D_O_K;
15815 }
15816
15817 void call_cheats_dlg();
15818 int32_t onCheats()
15819 {
15820 call_cheats_dlg();
15821 return D_O_K;
15822 }
15823
15824 bool do_x_button(BITMAP *dest, int32_t x, int32_t y)
15825 {
15826 bool over=false;
15827
15828 while(gui_mouse_b())
15829 {
15830 custom_vsync();
15831
15832 if(isinRect(gui_mouse_x(),gui_mouse_y(),x,y,x+15,y+13))
15833 {
15834 if(!over)
15835 {
15836 draw_x_button(dest, x, y, D_SELECTED);
15837 over=true;
15838 }
15839 }
15840 else
15841 {
15842 if(over)
15843 {
15844 draw_x_button(dest, x, y, 0);
15845 over=false;
15846 }
15847 }
15848 }
15849
15850 return over;
15851 }
15852
15853 bool do_question_button(BITMAP *dest, int32_t x, int32_t y)
15854 {
15855 bool over=false;
15856
15857 while(gui_mouse_b())
15858 {
15859 custom_vsync();
15860
15861 if(isinRect(gui_mouse_x(),gui_mouse_y(),x,y,x+15,y+13))
15862 {
15863 if(!over)
15864 {
15865 draw_question_button(dest, x, y, D_SELECTED);
15866 over=true;
15867 }
15868 }
15869 else
15870 {
15871 if(over)
15872 {
15873 draw_question_button(dest, x, y, 0);
15874 over=false;
15875 }
15876 }
15877 }
15878
15879 return over;
15880 }
15881
15882
15883 int32_t d_dummy_proc(int32_t,DIALOG *,int32_t)
15884 {
15885 return D_O_K;
15886 }
15887
15888 static int32_t last_combo=0;
15889 static int32_t last_cset=0;
15890
3/4
✓ Branch 0 taken 98304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 98292 times.
✓ Branch 3 taken 12 times.
98304 static combo_alias temp_aliases[MAXCOMBOALIASES];
15891
15892 extern int32_t scheme[jcMAX];
15893
15894 int32_t d_comboa_proc(int32_t msg,DIALOG *d,int32_t c)
15895 {
15896 //these are here to bypass compiler warnings about unused arguments
15897 c=c;
15898
15899 combo_alias *combo;
15900 combo = &temp_aliases[comboa_cnt];
15901 int32_t position;
15902 int32_t cur_layer, temp_layer;
15903 int32_t lay_count=0;
15904 int32_t size = 2;
15905
15906 int32_t cx1=(gui_mouse_x()-d->x-(120-(combo->width*8)));
15907 int32_t cy1=(gui_mouse_y()-d->y-(80-(combo->height*8)));
15908 int32_t cx=cx1/(16*size);
15909 int32_t cy=cy1/(16*size);
15910
15911 int32_t co,cs;
15912
15913
15914 switch(msg)
15915 {
15916 case MSG_CLICK:
15917 if((cx>combo->width)||(cx1<0))
15918 return D_O_K;
15919
15920 if((cy>combo->height)||(cy1<0))
15921 return D_O_K;
15922
15923 for(int32_t j=0; j<layer_cnt; j++)
15924 {
15925 if(combo->layermask&(1<<j))
15926 lay_count++;
15927 }
15928
15929 position=(lay_count)*(combo->width+1)*(combo->height+1);
15930 position+=(cy*(combo->width+1))+cx;
15931
15932 if(key[KEY_LSHIFT]||key[KEY_RSHIFT])
15933 {
15934 combo->combos[position] = 0;
15935 combo->csets[position] = 0;
15936
15937 while(gui_mouse_b())
15938 {
15939 /* do nothing */
15940 rest(1);
15941 }
15942
15943 return D_REDRAW;
15944 }
15945
15946 co=combo->combos[position];
15947 cs=combo->csets[position];
15948
15949 if((co==0)||(key[KEY_ZC_LCONTROL]))
15950 {
15951 co=last_combo;
15952 cs=last_cset;
15953 }
15954
15955 if((select_combo_2(co,cs)))
15956 {
15957 last_combo = co;
15958 last_cset = cs;
15959
15960 combo->combos[position]=co;
15961 combo->csets[position]=cs;
15962 }
15963
15964 return D_REDRAW;
15965 break;
15966
15967 case MSG_DRAW:
15968 BITMAP *buf = create_bitmap_ex(8,d->w,d->h);
15969
15970 if(buf)
15971 {
15972 clear_bitmap(buf);
15973
15974 for(int32_t z=0; z<=comboa_lmasktotal(combo->layermask); z++)
15975 {
15976 int32_t k=0;
15977 cur_layer=0;
15978 temp_layer=combo->layermask;
15979
15980 while((temp_layer!=0)&&(k<z))
15981 {
15982 if(temp_layer&1)
15983 {
15984 k++;
15985 }
15986
15987 cur_layer++;
15988 temp_layer = temp_layer>>1;
15989 }
15990
15991 for(int32_t y=0; (y<d->h)&&((y/16)<=combo->height); y+=16)
15992 {
15993 for(int32_t x=0; (x<d->w)&&((x/16)<=combo->width); x+=16)
15994 {
15995 int32_t cpos = (z*(combo->width+1)*(combo->height+1))+(((y/16)*(combo->width+1))+(x/16));
15996
15997 if(combo->combos[cpos])
15998 {
15999 if(!((d-1)->flags&D_SELECTED)||(cur_layer==layer_cnt))
16000 {
16001 if(z==0)
16002 {
16003 puttile16(buf,combobuf[combo->combos[cpos]].tile,x,y,combo->csets[cpos],combobuf[combo->combos[cpos]].flip);
16004 }
16005 else
16006 {
16007 overtile16(buf,combobuf[combo->combos[cpos]].tile,x,y,combo->csets[cpos],combobuf[combo->combos[cpos]].flip);
16008 }
16009 }
16010 }
16011 }
16012 }
16013 }
16014
16015 rectfill(screen, d->x-2,d->y-2,d->x+256+2,d->y+176+2,jwin_pal[jcBOX]);
16016 int32_t dx = 120-(combo->width*8)+d->x;
16017 int32_t dy = 80-(combo->height*8)+d->y;
16018 stretch_blit(buf,screen,0,0,(combo->width+1)*16,(combo->height+1)*16,dx,dy,(combo->width+1)*16*size,(combo->height+1)*16*size);
16019 //blit(buf,screen,0,0,120-(combo->width*8)+d->x,80-(combo->height*8)+d->y,(combo->width+1)*16,(combo->height+1)*16);
16020 (d-11)->w = (combo->width+1)*16*size+2;
16021 (d-11)->h = (combo->height+1)*16*size+2;
16022 (d-11)->x = 120-(combo->width*8)+4*size+2+(d-14)->x;
16023 (d-11)->y = 80-(combo->height*8)+25*size+2+(d-14)->y;
16024 object_message((d-11),MSG_DRAW,0);
16025
16026 destroy_bitmap(buf);
16027 }
16028
16029 break;
16030 }
16031
16032 return D_O_K;
16033 }
16034
16035 void draw_combo_alias_thumbnail(BITMAP *dest, combo_alias const* combo, int32_t x, int32_t y, int32_t size)
16036 {
16037 if(!combo->combo)
16038 {
16039 int32_t cur_layer, temp_layer;
16040
16041 int32_t cw=combo->width+1;
16042 int32_t ch=combo->height+1;
16043 int32_t dw=cw<<4;
16044 int32_t dh=ch<<4;
16045 int32_t sw=16, sh=16, sx=0, sy=0;
16046
16047 if(cw<ch)
16048 {
16049 sw=((cw<<4)/ch);
16050 sx=((16-sw)>>1);
16051 }
16052 else
16053 {
16054 sh=((ch<<4)/cw);
16055 sy=((16-sh)>>1);
16056 }
16057
16058 BITMAP *buf = create_bitmap_ex(8,dw,dh);
16059 BITMAP *buf2 = create_bitmap_ex(8, 16*size, 16*size);
16060 clear_bitmap(buf);
16061 clear_bitmap(buf2);
16062
16063 if(buf&&(combo->width>0||combo->height>0||combo->combos[0]>0))
16064 {
16065 clear_bitmap(buf);
16066
16067 for(int32_t z=0; z<=comboa_lmasktotal(combo->layermask); z++)
16068 {
16069 int32_t k=0;
16070 cur_layer=0;
16071 temp_layer=combo->layermask;
16072
16073 while((temp_layer!=0)&&(k<z))
16074 {
16075 if(temp_layer&1)
16076 {
16077 k++;
16078 }
16079
16080 cur_layer++;
16081 temp_layer = temp_layer>>1;
16082 }
16083
16084 for(int32_t y2=0; (y2<dh)&&((y2>>4)<=combo->height); y2+=16)
16085 {
16086 for(int32_t x2=0; (x2<dw)&&((x2>>4)<=combo->width); x2+=16)
16087 {
16088 int32_t cpos = (z*(combo->width+1)*(combo->height+1))+(((y2/16)*(combo->width+1))+(x2/16));
16089
16090 if(combo->combos[cpos])
16091 {
16092 if(z==0)
16093 {
16094 puttile16(buf,combobuf[combo->combos[cpos]].tile,x2,y2,combo->csets[cpos],combobuf[combo->combos[cpos]].flip);
16095 }
16096 else
16097 {
16098 overtile16(buf,combobuf[combo->combos[cpos]].tile,x2,y2,combo->csets[cpos],combobuf[combo->combos[cpos]].flip);
16099 }
16100 }
16101 }
16102 }
16103 }
16104
16105 stretch_blit(buf, buf2, 0, 0, (cw*16), (ch*16), sx*size, sy*size, sw*size, sh*size);
16106 blit(buf2, dest, 0, 0, x, y, 16*size, 16*size);
16107 }
16108 else
16109 {
16110 rectfill(dest,x,y,x+16*size-1,y+16*size-1,0);
16111 rectfill(dest,x+3*size,y+3*size,x+12*size,y+12*size,vc(4));
16112 }
16113
16114 if(buf)
16115 destroy_bitmap(buf);
16116
16117 if(buf2)
16118 destroy_bitmap(buf2);
16119 }
16120 else
16121 {
16122 if(combobuf[combo->combo].tile>0)
16123 {
16124 rectfill(dest,x,y,x+16*size-1,y+16*size-1,0);
16125 put_combo(dest, x, y, combo->combo, combo->cset, 0, 0, size);
16126 }
16127 else
16128 {
16129 rectfill(dest,x,y,x+16*size-1,y+16*size-1,0);
16130 rectfill(dest,x+3*size,y+3*size,x+12*size,y+12*size,vc(4));
16131 }
16132 }
16133 }
16134
16135 int32_t d_comboat_proc(int32_t msg,DIALOG *d,int32_t)
16136 {
16137 switch(msg)
16138 {
16139 case MSG_CLICK:
16140 {
16141 int32_t c2;
16142 int32_t cs;
16143 c2=temp_aliases[comboa_cnt].combo;
16144 cs=temp_aliases[comboa_cnt].cset;
16145
16146 if(gui_mouse_b()&2) //right mouse button
16147 {
16148 if(c2==0&&cs==0&&!(gui_mouse_b()&1))
16149 {
16150 return D_O_K;
16151 }
16152
16153 temp_aliases[comboa_cnt].combo=0;
16154 temp_aliases[comboa_cnt].cset=0;
16155 }
16156
16157 if(gui_mouse_b()&1) //left mouse button
16158 {
16159 if(select_combo_2(c2, cs))
16160 {
16161 temp_aliases[comboa_cnt].combo=c2;
16162 temp_aliases[comboa_cnt].cset=cs;
16163 }
16164
16165 return D_REDRAW;
16166 }
16167 else
16168 {
16169 return D_REDRAWME;
16170 }
16171 }
16172 break;
16173
16174 case MSG_DRAW:
16175 draw_combo_alias_thumbnail(screen, &temp_aliases[comboa_cnt], d->x-1, d->y-1,2);
16176 break;
16177
16178 default:
16179 break;
16180 }
16181
16182 return D_O_K;
16183 }
16184
16185 int32_t d_comboa_radio_proc(int32_t msg,DIALOG *d,int32_t c);
16186
16187 static DIALOG orgcomboa_dlg[] =
16188 {
16189 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
16190 { jwin_win_proc, 0, 0, 200, 161, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Organize Combo Aliases", NULL, NULL },
16191 { jwin_button_proc, 27, 130, 61, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
16192 { jwin_button_proc, 112, 130, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
16193
16194 { jwin_radio_proc, 10, 40, 33, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Copy", NULL, NULL },
16195 { jwin_text_proc, 10, 50, 33, 9, 0, 0, 0, 0, 0, 0, (void *) "", NULL, NULL },
16196 // { jwin_radio_proc, 10, 50, 33, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Move", NULL, NULL },
16197 { jwin_radio_proc, 10, 60, 33, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Swap", NULL, NULL },
16198 /* 6 */ { jwin_edit_proc, 110, 35, 32, 16, vc(12), vc(1), 0, 0, 4, 0, NULL, NULL, NULL },
16199 { jwin_edit_proc, 110, 55, 32, 16, vc(12), vc(1), 0, 0, 4, 0, NULL, NULL, NULL },
16200 { jwin_text_proc, 60, 40, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Source", NULL, NULL },
16201 { jwin_text_proc, 60, 60, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Dest", NULL, NULL},
16202 { jwin_radio_proc, 10, 80, 60, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Insert new (before source)", NULL, NULL },
16203 { jwin_radio_proc, 10, 100, 60, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Delete source", NULL, NULL },
16204 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16205 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
16206 };
16207
16208 static DIALOG newcomboa_dlg[] =
16209 {
16210 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
16211 { jwin_win_proc, 0, 0, 200, 161, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Combo Alias Properties", NULL, NULL },
16212 { jwin_button_proc, 27, 130, 61, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
16213 { jwin_button_proc, 112, 130, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
16214 { jwin_text_proc, 24, 34, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Alias Width", NULL, NULL },
16215 { jwin_text_proc, 24, 52, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Alias Height", NULL, NULL },
16216 { jwin_text_proc, 24, 70, 100, 8, 0, 0, 0, 0, 0, 0, (void *) "Layers to Draw On:", NULL, NULL },
16217 { jwin_edit_proc, 104, 30, 28-6, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
16218 { jwin_edit_proc, 122, 48, 28-6, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
16219 { jwin_check_proc, 24, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "1", NULL, NULL },
16220 { jwin_check_proc, 50, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "2", NULL, NULL },
16221 { jwin_check_proc, 76, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "3", NULL, NULL },
16222 { jwin_check_proc, 102, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "4", NULL, NULL },
16223 { jwin_check_proc, 128, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "5", NULL, NULL },
16224 { jwin_check_proc, 154, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "6", NULL, NULL },
16225
16226
16227 // { jwin_text_proc, 24, 106, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Copy to :", NULL, NULL },
16228 //15
16229 // { jwin_edit_proc, 100, 100, 28-6, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
16230 // { jwin_check_proc, 84, 106, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "", NULL, NULL },
16231
16232 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16233 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
16234 };
16235
16236 bool swapComboAlias(int32_t source, int32_t dest)
16237 {
16238 if(source==dest)
16239 return false;
16240 zc_swap(temp_aliases[source],temp_aliases[dest]);
16241 return true;
16242 }
16243
16244
16245 bool copyComboAlias(int32_t source, int32_t dest)
16246 {
16247 if(source == dest)
16248 return false;
16249 temp_aliases[dest] = temp_aliases[source];
16250 return true;
16251 }
16252
16253 int32_t getcurrentcomboalias();
16254
16255 int32_t onOrgComboAliases()
16256 {
16257 char cSrc[8];
16258 char cDest[8];
16259 sprintf(cSrc,"%d", getcurrentcomboalias());
16260 strcpy(cDest,cSrc);
16261 int32_t iSrc = 0;
16262 int32_t iDest = 0;
16263
16264 //sprintf(cSrc,"0");
16265 //sprintf(cDest,"0");
16266 orgcomboa_dlg[0].dp2=get_zc_font(font_lfont);
16267 orgcomboa_dlg[6].dp= cSrc;
16268 orgcomboa_dlg[7].dp= cDest;
16269 int32_t ret = 1;
16270 large_dialog(orgcomboa_dlg);
16271 do
16272 {
16273 iSrc = atoi((char*)orgcomboa_dlg[6].dp);
16274 iDest = atoi((char*)orgcomboa_dlg[7].dp);
16275 ret = do_zqdialog(orgcomboa_dlg,-1);
16276
16277 if(ret!=1) return ret;
16278
16279 if((atoi((char*) orgcomboa_dlg[6].dp))<0 || (atoi((char*) orgcomboa_dlg[6].dp)) > MAXCOMBOALIASES-1)
16280 {
16281 displayinfo("Error",fmt::format("Invalid source (range 0-{})", MAXCOMBOALIASES-1));
16282 ret = 1;
16283 }
16284
16285 // 10,11=ins, del
16286 if(orgcomboa_dlg[10].flags & D_SELECTED) //insert
16287 {
16288 for(int32_t j=MAXCOMBOALIASES-1; j>(atoi((char*) orgcomboa_dlg[6].dp)); --j)
16289 copyComboAlias(j-1,j);
16290 ret = -1;
16291 }
16292
16293 if(orgcomboa_dlg[11].flags & D_SELECTED) //delete
16294 {
16295 for(int32_t j=(atoi((char*) orgcomboa_dlg[6].dp)); j<MAXCOMBOALIASES-1; ++j)
16296 copyComboAlias(j+1,j);
16297 ret = -1;
16298 }
16299
16300 if((atoi((char*) orgcomboa_dlg[6].dp)) == (atoi((char*) orgcomboa_dlg[7].dp)))
16301 {
16302 displayinfo("Error","Source and dest can't be the same.");
16303 ret = 1;
16304 }
16305
16306 if((atoi((char*) orgcomboa_dlg[7].dp)) < 0 || (atoi((char*) orgcomboa_dlg[7].dp)) > MAXCOMBOALIASES-1)
16307 {
16308 displayinfo("Error",fmt::format("Invalid dest (range 0-{})", MAXCOMBOALIASES-1));
16309 ret = 1;
16310 }
16311
16312 if(orgcomboa_dlg[3].flags & D_SELECTED) //copy
16313 {
16314 copyComboAlias((atoi((char*) orgcomboa_dlg[6].dp)),(atoi((char*) orgcomboa_dlg[7].dp)));
16315 ret = -1;
16316 }
16317
16318 if(orgcomboa_dlg[5].flags & D_SELECTED) //swap
16319 {
16320 swapComboAlias((atoi((char*) orgcomboa_dlg[6].dp)),(atoi((char*) orgcomboa_dlg[7].dp)));
16321 ret = -1;
16322 }
16323 }
16324 while(ret==1);
16325 return ret;
16326 }
16327
16328 int32_t onNewComboAlias()
16329 {
16330 combo_alias *combo;
16331 combo = &temp_aliases[comboa_cnt];
16332
16333 char cwidth[5];
16334 char cheight[5];
16335 // char cp[3];
16336
16337 word temp_combos[16*11*7];
16338 byte temp_csets[16*11*7];
16339 sprintf(cwidth, "%d", combo->width+1);
16340 sprintf(cheight, "%d", combo->height+1);
16341 int32_t old_count = (comboa_lmasktotal(combo->layermask)+1)*(combo->width+1)*(combo->height+1);
16342 int32_t old_width=combo->width;
16343 int32_t old_height=combo->height;
16344 int32_t oldlayer=combo->layermask;
16345
16346 for(int32_t i=0; i<old_count; i++)
16347 {
16348 temp_csets[i] = combo->csets[i];
16349 temp_combos[i] = combo->combos[i];
16350 }
16351
16352 newcomboa_dlg[0].dp2 = get_zc_font(font_lfont);
16353 newcomboa_dlg[6].dp = cwidth;
16354 newcomboa_dlg[7].dp = cheight;
16355 newcomboa_dlg[8].flags = (combo->layermask&1)? D_SELECTED : 0;
16356 newcomboa_dlg[9].flags = (combo->layermask&2)? D_SELECTED : 0;
16357 newcomboa_dlg[10].flags = (combo->layermask&4)? D_SELECTED : 0;
16358 newcomboa_dlg[11].flags = (combo->layermask&8)? D_SELECTED : 0;
16359 newcomboa_dlg[12].flags = (combo->layermask&16)? D_SELECTED : 0;
16360 newcomboa_dlg[13].flags = (combo->layermask&32)? D_SELECTED : 0;
16361
16362 large_dialog(newcomboa_dlg);
16363
16364 int32_t ret = do_zqdialog(newcomboa_dlg,-1);
16365
16366 if(ret==1)
16367 {
16368 combo->width = ((atoi(cwidth)-1)<16)?zc_max(0,(atoi(cwidth)-1)):15;
16369 combo->height = ((atoi(cheight)-1)<11)?zc_max(0,(atoi(cheight)-1)):10;
16370 combo->layermask=0;
16371 combo->layermask |= (newcomboa_dlg[8].flags&D_SELECTED)?1:0;
16372 combo->layermask |= (newcomboa_dlg[9].flags&D_SELECTED)?2:0;
16373 combo->layermask |= (newcomboa_dlg[10].flags&D_SELECTED)?4:0;
16374 combo->layermask |= (newcomboa_dlg[11].flags&D_SELECTED)?8:0;
16375 combo->layermask |= (newcomboa_dlg[12].flags&D_SELECTED)?16:0;
16376 combo->layermask |= (newcomboa_dlg[13].flags&D_SELECTED)?32:0;
16377
16378 int32_t new_count = (comboa_lmasktotal(combo->layermask)+1)*(combo->width+1)*(combo->height+1);
16379
16380 combo->combos.clear();
16381 combo->csets.clear();
16382
16383 int32_t j=1;
16384 int32_t old_size=(old_width+1)*(old_height+1);
16385 int32_t new_start[7] =
16386 {
16387 0,
16388 ((combo->width+1)*(combo->height+1)*(1)),
16389 ((combo->width+1)*(combo->height+1)*(2)),
16390 ((combo->width+1)*(combo->height+1)*(3)),
16391 ((combo->width+1)*(combo->height+1)*(4)),
16392 ((combo->width+1)*(combo->height+1)*(5)),
16393 ((combo->width+1)*(combo->height+1)*(6))
16394 };
16395 int32_t new_layers[6] = {0,0,0,0,0,0};
16396 int32_t temp_layer = combo->layermask;
16397 int32_t temp_old = oldlayer;
16398 int32_t old_layers[6] = {0,0,0,0,0,0};
16399 int32_t k=1;
16400
16401 for(int32_t i=0; (i<6)&&(temp_layer!=0); j++,temp_layer>>=1,temp_old>>=1)
16402 {
16403 if(temp_layer&1)
16404 {
16405 new_layers[i] = j;
16406 //if(oldlayer&(1<<(j-1))) old_layers[i] = k++;
16407 i++;
16408 }
16409
16410 if(temp_old&1)
16411 {
16412 if(temp_layer&1)
16413 {
16414 old_layers[i-1] = k;
16415 }
16416
16417 k++;
16418 }
16419 }
16420
16421 for(int32_t i=0; i<new_count; i++)
16422 {
16423 if(i>=new_start[6])
16424 {
16425 //oldl=oldlayer>>(new_layers[5]-1);
16426 j=i-new_start[6];
16427
16428 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[5]-1))))
16429 {
16430 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[5])];
16431 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[5])];
16432 }
16433 else
16434 {
16435 combo->combos[i] = 0;
16436 combo->csets[i] = 0;
16437 }
16438 }
16439 else if(i>=new_start[5])
16440 {
16441 //oldl=oldlayer>>(new_layers[4]-1);
16442 j=i-new_start[5];
16443
16444 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[4]-1))))
16445 {
16446 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[4])];
16447 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[4])];
16448 }
16449 else
16450 {
16451 combo->combos[i] = 0;
16452 combo->csets[i] = 0;
16453 }
16454 }
16455 else if(i>=new_start[4])
16456 {
16457 //oldl=oldlayer>>(new_layers[3]-1);
16458 j=i-new_start[4];
16459
16460 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[3]-1))))
16461 {
16462 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[3])];
16463 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[3])];
16464 }
16465 else
16466 {
16467 combo->combos[i] = 0;
16468 combo->csets[i] = 0;
16469 }
16470 }
16471 else if(i>=new_start[3])
16472 {
16473 //oldl=oldlayer>>(new_layers[2]-1);
16474 j=i-new_start[3];
16475
16476 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[2]-1))))
16477 {
16478 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[2])];
16479 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[2])];
16480 }
16481 else
16482 {
16483 combo->combos[i] = 0;
16484 combo->csets[i] = 0;
16485 }
16486 }
16487 else if(i>=new_start[2])
16488 {
16489 //oldl=oldlayer>>(new_layers[1]-1);
16490 j=i-new_start[2];
16491
16492 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[1]-1))))
16493 {
16494 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[1])];
16495 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[1])];
16496 }
16497 else
16498 {
16499 combo->combos[i] = 0;
16500 combo->csets[i] = 0;
16501 }
16502 }
16503 else if(i>=new_start[1])
16504 {
16505 //oldl=oldlayer>>(new_layers[0]-1);
16506 j=i-new_start[1];
16507
16508 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[0]-1))))
16509 {
16510 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[0])];
16511 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[0])];
16512 }
16513 else
16514 {
16515 combo->combos[i] = 0;
16516 combo->csets[i] = 0;
16517 }
16518 }
16519 else if(i>=new_start[0])
16520 {
16521 if(((i/(combo->width+1))<=old_height)&&((i%(combo->width+1))<=old_width))
16522 {
16523 combo->combos[i] = temp_combos[(i%(combo->width+1))+((old_width+1)*(i/(combo->width+1)))];
16524 combo->csets[i] = temp_csets[(i%(combo->width+1))+((old_width+1)*(i/(combo->width+1)))];
16525 }
16526 else
16527 {
16528 combo->combos[i] = 0;
16529 combo->csets[i] = 0;
16530 }
16531 }
16532 }
16533
16534 set_comboaradio(combo->layermask);
16535 }
16536
16537 return ret;
16538 }
16539
16540 int32_t d_orgcomboa_proc(int32_t msg, DIALOG *d, int32_t c)
16541 {
16542 //these are here to bypass compiler warnings about unused arguments
16543 c=c;
16544
16545 int32_t down=0;
16546 int32_t selected=(d->flags&D_SELECTED)?1:0;
16547 int32_t last_draw;
16548
16549 switch(msg)
16550 {
16551
16552 case MSG_DRAW:
16553 {
16554 FONT *tfont=font;
16555 font=get_zc_font(font_lfont_l);
16556 jwin_draw_text_button(screen, d->x, d->y, d->w, d->h, (char*)d->dp, d->flags, true);
16557 font=tfont;
16558 }
16559 break;
16560
16561 case MSG_WANTFOCUS:
16562 return D_WANTFOCUS;
16563
16564 case MSG_KEY:
16565 /* close dialog? */
16566 onOrgComboAliases();
16567 return D_REDRAW;
16568
16569 /* or just toggle */
16570 /*d->flags ^= D_SELECTED;
16571 object_message(d, MSG_DRAW, 0);
16572 break;*/
16573
16574 case MSG_CLICK:
16575 last_draw = 0;
16576
16577 /* track the mouse until it is released */
16578 while(gui_mouse_b())
16579 {
16580 down = mouse_in_rect(d->x, d->y, d->w, d->h);
16581
16582 /* redraw? */
16583 if(last_draw != down)
16584 {
16585 if(down != selected)
16586 d->flags |= D_SELECTED;
16587 else
16588 d->flags &= ~D_SELECTED;
16589
16590 object_message(d, MSG_DRAW, 0);
16591 last_draw = down;
16592 }
16593
16594 /* let other objects continue to animate */
16595 broadcast_dialog_message(MSG_IDLE, 0);
16596 }
16597
16598 /* redraw in normal state */
16599 if(down)
16600 {
16601 if(d->flags&D_EXIT)
16602 {
16603 d->flags &= ~D_SELECTED;
16604 object_message(d, MSG_DRAW, 0);
16605 }
16606 }
16607
16608 /* should we close the dialog? */
16609 if(down)
16610 {
16611 onOrgComboAliases();
16612 return D_REDRAW;
16613 }
16614
16615 break;
16616 }
16617
16618 return D_O_K;
16619 }
16620
16621 int32_t d_comboabutton_proc(int32_t msg, DIALOG *d, int32_t c)
16622 {
16623 //these are here to bypass compiler warnings about unused arguments
16624 c=c;
16625
16626 int32_t down=0;
16627 int32_t selected=(d->flags&D_SELECTED)?1:0;
16628 int32_t last_draw;
16629
16630 switch(msg)
16631 {
16632
16633 case MSG_DRAW:
16634 {
16635 FONT *tfont=font;
16636 font=get_zc_font(font_lfont_l);
16637 jwin_draw_text_button(screen, d->x, d->y, d->w, d->h, (char*)d->dp, d->flags, true);
16638 font=tfont;
16639 }
16640 break;
16641
16642 case MSG_WANTFOCUS:
16643 return D_WANTFOCUS;
16644
16645 case MSG_KEY:
16646 /* close dialog? */
16647 onNewComboAlias();
16648 return D_REDRAW;
16649
16650 /* or just toggle */
16651 /*d->flags ^= D_SELECTED;
16652 object_message(d, MSG_DRAW, 0);
16653 break;*/
16654
16655 case MSG_CLICK:
16656 last_draw = 0;
16657
16658 /* track the mouse until it is released */
16659 while(gui_mouse_b())
16660 {
16661 down = mouse_in_rect(d->x, d->y, d->w, d->h);
16662
16663 /* redraw? */
16664 if(last_draw != down)
16665 {
16666 if(down != selected)
16667 d->flags |= D_SELECTED;
16668 else
16669 d->flags &= ~D_SELECTED;
16670
16671 object_message(d, MSG_DRAW, 0);
16672 last_draw = down;
16673 }
16674
16675 /* let other objects continue to animate */
16676 broadcast_dialog_message(MSG_IDLE, 0);
16677 }
16678
16679 /* redraw in normal state */
16680 if(down)
16681 {
16682 if(d->flags&D_EXIT)
16683 {
16684 d->flags &= ~D_SELECTED;
16685 object_message(d, MSG_DRAW, 0);
16686 }
16687 }
16688
16689 /* should we close the dialog? */
16690 if(down)
16691 {
16692 onNewComboAlias();
16693 return D_REDRAW;
16694 }
16695
16696 break;
16697 }
16698
16699 return D_O_K;
16700 }
16701
16702 int32_t d_comboacheck_proc(int32_t msg, DIALOG *d, int32_t c)
16703 {
16704 int32_t temp = d->flags&D_SELECTED;
16705 int32_t ret=jwin_checkfont_proc(msg,d,c);
16706
16707 if(temp != (d->flags&D_SELECTED))
16708 {
16709 return D_REDRAW;
16710 }
16711
16712 return ret;
16713 }
16714
16715 static DIALOG editcomboa_dlg[] =
16716 {
16717 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
16718 { jwin_win_proc, 0, 0, 320, 240, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Combo Alias Edit", NULL, NULL },
16719 { jwin_button_proc, 148, 212, 61, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
16720 { jwin_button_proc, 232, 212, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
16721 { jwin_frame_proc, 4+121, 28+81, 1, 1, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
16722 { d_comboabutton_proc, 25, 212, 81, 21, vc(14), vc(1), 'p', D_EXIT, 0, 0, (void *) "&Properties", NULL, NULL },
16723 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16724 { d_comboa_radio_proc, 285, 44, 30, 8+1, vc(14), vc(1), 0, D_SELECTED, 0, 0, (void *) "0", NULL, NULL },
16725 { d_comboa_radio_proc, 285, 54, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "1", NULL, NULL },
16726 { d_comboa_radio_proc, 285, 64, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "2", NULL, NULL },
16727 { d_comboa_radio_proc, 285, 74, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "3", NULL, NULL },
16728 { d_comboa_radio_proc, 285, 84, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "4", NULL, NULL },
16729
16730 { d_comboa_radio_proc, 285, 94, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "5", NULL, NULL },
16731 { d_comboa_radio_proc, 285, 104, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "6", NULL, NULL },
16732 { d_comboacheck_proc, 285, 164, 17, 9, vc(12), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
16733 { d_comboa_proc, 6, 27, 256, 176, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16734 { jwin_ctext_proc, 290, 176, 27, 8, 0, 0, 0, 0, 0, 0, (void *) "Only Show", NULL, NULL },
16735 { jwin_ctext_proc, 290, 186, 27, 8, 0, 0, 0, 0, 0, 0, (void *) "Current", NULL, NULL },
16736 { jwin_ctext_proc, 290, 196, 27, 8, 0, 0, 0, 0, 0, 0, (void *) "Layer", NULL, NULL },
16737 { jwin_ctext_proc, 290, 122, 27, 8, 0, 0, 0, 0, 0, 0, (void *) "Thumbnail", NULL, NULL },
16738 { jwin_frame_proc, 280, 132, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
16739 { d_comboat_proc, 282, 134, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16740
16741 //21
16742 { d_orgcomboa_proc, 106, 212, 21, 21, vc(14), vc(1), 'p', D_EXIT, 0, 0, (void *) "&Org", NULL, NULL },
16743 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16744 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
16745 };
16746
16747 int32_t getcurrentcomboalias()
16748 {
16749 return editcomboa_dlg[5].d1;
16750 }
16751
16752 int32_t d_comboa_radio_proc(int32_t msg,DIALOG *d,int32_t c)
16753 {
16754 int32_t temp = layer_cnt;
16755 int32_t ret = jwin_radiofont_proc(msg,d,c);
16756
16757 if(editcomboa_dlg[6].flags&D_SELECTED) layer_cnt=0;
16758 else if(editcomboa_dlg[7].flags&D_SELECTED) layer_cnt=1;
16759 else if(editcomboa_dlg[8].flags&D_SELECTED) layer_cnt=2;
16760 else if(editcomboa_dlg[9].flags&D_SELECTED) layer_cnt=3;
16761 else if(editcomboa_dlg[10].flags&D_SELECTED) layer_cnt=4;
16762 else if(editcomboa_dlg[11].flags&D_SELECTED) layer_cnt=5;
16763 else if(editcomboa_dlg[12].flags&D_SELECTED) layer_cnt=6;
16764
16765 if(temp != layer_cnt)
16766 {
16767 return D_REDRAW;
16768 }
16769
16770 return ret;
16771 }
16772
16773 int32_t set_comboaradio(byte layermask)
16774 {
16775 if(editcomboa_dlg[7].flags&D_SELECTED) editcomboa_dlg[7].flags &= ~D_SELECTED;
16776
16777 if(editcomboa_dlg[8].flags&D_SELECTED) editcomboa_dlg[8].flags &= ~D_SELECTED;
16778
16779 if(editcomboa_dlg[9].flags&D_SELECTED) editcomboa_dlg[9].flags &= ~D_SELECTED;
16780
16781 if(editcomboa_dlg[10].flags&D_SELECTED) editcomboa_dlg[10].flags &= ~D_SELECTED;
16782
16783 if(editcomboa_dlg[11].flags&D_SELECTED) editcomboa_dlg[11].flags &= ~D_SELECTED;
16784
16785 if(editcomboa_dlg[12].flags&D_SELECTED) editcomboa_dlg[12].flags &= ~D_SELECTED;
16786
16787 if(!(layermask&1)) editcomboa_dlg[7].flags |= D_DISABLED;
16788 else editcomboa_dlg[7].flags &= ~D_DISABLED;
16789
16790 if(!(layermask&2)) editcomboa_dlg[8].flags |= D_DISABLED;
16791 else editcomboa_dlg[8].flags &= ~D_DISABLED;
16792
16793 if(!(layermask&4)) editcomboa_dlg[9].flags |= D_DISABLED;
16794 else editcomboa_dlg[9].flags &= ~D_DISABLED;
16795
16796 if(!(layermask&8)) editcomboa_dlg[10].flags |= D_DISABLED;
16797 else editcomboa_dlg[10].flags &= ~D_DISABLED;
16798
16799 if(!(layermask&16)) editcomboa_dlg[11].flags |= D_DISABLED;
16800 else editcomboa_dlg[11].flags &= ~D_DISABLED;
16801
16802 if(!(layermask&32)) editcomboa_dlg[12].flags |= D_DISABLED;
16803 else editcomboa_dlg[12].flags &= ~D_DISABLED;
16804
16805 editcomboa_dlg[6].flags |= D_SELECTED;
16806 layer_cnt=0;
16807 return 1;
16808 }
16809
16810 int32_t onEditComboPool()
16811 {
16812 call_cpool_dlg(combo_pool_pos);
16813 return D_O_K;
16814 }
16815 int32_t onEditAutoCombo()
16816 {
16817 call_autocombo_dlg(combo_auto_pos);
16818 return D_O_K;
16819 }
16820 int32_t onEditComboAlias()
16821 {
16822 comboa_cnt = combo_apos;
16823 reset_combo_animations();
16824 reset_combo_animations2();
16825
16826 for(int32_t i=0; i<MAXCOMBOALIASES; i++)
16827 temp_aliases[i] = combo_aliases[i];
16828
16829 editcomboa_dlg[0].dp2 = get_zc_font(font_lfont);
16830 set_comboaradio(temp_aliases[comboa_cnt].layermask);
16831 editcomboa_dlg[5].d1 = comboa_cnt;
16832
16833 bool small_d1 = editcomboa_dlg[0].d1==0;
16834 large_dialog(editcomboa_dlg,2);
16835
16836 if(small_d1)
16837 {
16838 for(int32_t i=6; i<=12; i++)
16839 {
16840 editcomboa_dlg[i].w=30*1.5;
16841 editcomboa_dlg[i].h=9*1.5;
16842 }
16843
16844 editcomboa_dlg[13].w=17*1.5;
16845 editcomboa_dlg[13].h=9*1.5;
16846 editcomboa_dlg[4].w=81*1.5;
16847 editcomboa_dlg[4].h=21*1.5;
16848 editcomboa_dlg[4].dp2=get_zc_font(font_lfont_l);
16849 editcomboa_dlg[21].w=21*1.5;
16850 editcomboa_dlg[21].h=21*1.5;
16851 editcomboa_dlg[21].dp2=get_zc_font(font_lfont_l);
16852 }
16853
16854 int32_t ret=do_zqdialog(editcomboa_dlg,-1);
16855
16856 if(ret==1)
16857 {
16858 mark_save_dirty();
16859
16860 for(int32_t i=0; i<MAXCOMBOALIASES; i++)
16861 combo_aliases[i] = temp_aliases[i];
16862 }
16863
16864 setup_combo_animations();
16865 setup_combo_animations2();
16866 return D_O_K;
16867 }
16868 void call_calias_dlg(int index)
16869 {
16870 combo_apos = comboa_cnt = index;
16871 onEditComboAlias();
16872 }
16873
16874 int32_t onSelectFFCombo()
16875 {
16876 FFCListerDialog().show();
16877 return D_O_K;
16878 }
16879
16880 static int32_t as_ffc_list[] = { 4, 5, 6, -1};
16881 static int32_t as_global_list[] = { 7, 8, 9, -1}; //Why does putting 15 in here not place my message only on the global tab? ~Joe
16882 static int32_t as_item_list[] = { 10, 11, 12, -1};
16883 static int32_t as_npc_list[] = { 18, 19, 20, -1}; //npc scripts TAB
16884 static int32_t as_lweapon_list[] = { 21, 22, 23, -1}; //lweapon scripts TAB
16885 static int32_t as_eweapon_list[] = { 24, 25, 26, -1}; //eweapon scripts TAB
16886 static int32_t as_hero_list[] = { 27, 28, 29, -1}; //hero scripts TAB
16887 static int32_t as_screen_list[] = { 30, 31, 32, -1}; //screendata scripts TAB
16888 static int32_t as_dmap_list[] = { 33, 34, 35, -1}; //dmapdata scripts TAB
16889 static int32_t as_itemsprite_list[] = { 36, 37, 38, -1}; //dmapdata scripts TAB
16890 static int32_t as_comboscript_list[] = { 39, 40, 41, -1}; //combodata scripts TAB
16891 static int32_t as_genericscript_list[] = { 45, 46, 47, -1}; //generic scripts TAB
16892 static int32_t as_subscreenscript_list[] = { 48, 49, 50, -1}; //generic scripts TAB
16893
16894 static TABPANEL assignscript_tabs[] =
16895 {
16896 // (text)
16897 { (char *)"FFC", D_SELECTED, as_ffc_list, 0, NULL },
16898 { (char *)"Global", 0, as_global_list, 0, NULL },
16899 { (char *)"Item", 0, as_item_list, 0, NULL },
16900 { (char *)"NPC", 0, as_npc_list, 0, NULL },
16901 { (char *)"LWeapon", 0, as_lweapon_list, 0, NULL },
16902 { (char *)"EWeapon", 0, as_eweapon_list, 0, NULL },
16903 { (char *)"Hero", 0, as_hero_list, 0, NULL },
16904 { (char *)"DMap", 0, as_dmap_list, 0, NULL },
16905 { (char *)"Screen", 0, as_screen_list, 0, NULL },
16906 { (char *)"Item Sprite", 0, as_itemsprite_list, 0, NULL },
16907 { (char *)"Combo", 0, as_comboscript_list, 0, NULL },
16908 { (char *)"Generic", 0, as_genericscript_list, 0, NULL },
16909 { (char *)"Subscreen", 0, as_subscreenscript_list, 0, NULL },
16910 { NULL, 0, NULL, 0, NULL }
16911 };
16912
16913 const char *assignffclist(int32_t index, int32_t *list_size)
16914 {
16915 if(index<0)
16916 {
16917 *list_size = (int32_t)ffcmap.size();
16918 return NULL;
16919 }
16920
16921 return ffcmap[index].output.c_str();
16922 }
16923
16924 const char *assigngloballist(int32_t index, int32_t *list_size)
16925 {
16926 if(index<0)
16927 {
16928 *list_size = (int32_t)globalmap.size();
16929 return NULL;
16930 }
16931
16932 return globalmap[index].output.c_str();
16933 }
16934
16935 const char *assigncombolist(int32_t index, int32_t *list_size)
16936 {
16937 if(index<0)
16938 {
16939 *list_size = (int32_t)comboscriptmap.size();
16940 return NULL;
16941 }
16942
16943 return comboscriptmap[index].output.c_str();
16944 }
16945
16946 const char *assigngenericlist(int32_t index, int32_t *list_size)
16947 {
16948 if(index<0)
16949 {
16950 *list_size = ((int32_t)genericmap.size());
16951 return NULL;
16952 }
16953
16954 return genericmap[index].output.c_str();
16955 }
16956
16957 const char *assignsubscreenlist(int32_t index, int32_t *list_size)
16958 {
16959 if(index<0)
16960 {
16961 *list_size = ((int32_t)subscreenmap.size());
16962 return NULL;
16963 }
16964
16965 return subscreenmap[index].output.c_str();
16966 }
16967
16968 const char *assignitemlist(int32_t index, int32_t *list_size)
16969 {
16970 if(index<0)
16971 {
16972 *list_size = (int32_t)itemmap.size();
16973 return NULL;
16974 }
16975
16976 return itemmap[index].output.c_str();
16977 }
16978 const char *assignnpclist(int32_t index, int32_t *list_size)
16979 {
16980 if(index<0)
16981 {
16982 *list_size = (int32_t)npcmap.size();
16983 return NULL;
16984 }
16985
16986 return npcmap[index].output.c_str();
16987 }
16988
16989 const char *assignlweaponlist(int32_t index, int32_t *list_size)
16990 {
16991 if(index<0)
16992 {
16993 *list_size = (int32_t)lwpnmap.size();
16994 return NULL;
16995 }
16996
16997 return lwpnmap[index].output.c_str();
16998 }
16999
17000 const char *assigneweaponlist(int32_t index, int32_t *list_size)
17001 {
17002 if(index<0)
17003 {
17004 *list_size = (int32_t)ewpnmap.size();
17005 return NULL;
17006 }
17007
17008 return ewpnmap[index].output.c_str();
17009 }
17010
17011 const char *assignplayerlist(int32_t index, int32_t *list_size)
17012 {
17013 if(index<0)
17014 {
17015 *list_size = (int32_t)playermap.size();
17016 return NULL;
17017 }
17018
17019 return playermap[index].output.c_str();
17020 }
17021
17022 const char *assigndmaplist(int32_t index, int32_t *list_size)
17023 {
17024 if(index<0)
17025 {
17026 *list_size = (int32_t)dmapmap.size();
17027 return NULL;
17028 }
17029
17030 return dmapmap[index].output.c_str();
17031 }
17032
17033 const char *assignscreenlist(int32_t index, int32_t *list_size)
17034 {
17035 if(index<0)
17036 {
17037 *list_size = (int32_t)screenmap.size();
17038 return NULL;
17039 }
17040
17041 return screenmap[index].output.c_str();
17042 }
17043
17044 const char *assignitemspritelist(int32_t index, int32_t *list_size)
17045 {
17046 if(index<0)
17047 {
17048 *list_size = (int32_t)itemspritemap.size();
17049 return NULL;
17050 }
17051
17052 return itemspritemap[index].output.c_str();
17053 }
17054
17055 const char *assignffcscriptlist(int32_t index, int32_t *list_size)
17056 {
17057 if(index<0)
17058 {
17059 *list_size = (int32_t)asffcscripts.size();
17060 return NULL;
17061 }
17062
17063 return asffcscripts[index].c_str();
17064 }
17065
17066 const char *assignglobalscriptlist(int32_t index, int32_t *list_size)
17067 {
17068 if(index<0)
17069 {
17070 *list_size = (int32_t)asglobalscripts.size();
17071 return NULL;
17072 }
17073
17074 return asglobalscripts[index].c_str();
17075 }
17076
17077 const char *assignitemscriptlist(int32_t index, int32_t *list_size)
17078 {
17079 if(index<0)
17080 {
17081 *list_size = (int32_t)asitemscripts.size();
17082 return NULL;
17083 }
17084
17085 return asitemscripts[index].c_str();
17086 }
17087
17088 const char *assignnpcscriptlist(int32_t index, int32_t *list_size)
17089 {
17090 if(index<0)
17091 {
17092 *list_size = (int32_t)asnpcscripts.size();
17093 return NULL;
17094 }
17095
17096 return asnpcscripts[index].c_str();
17097 }
17098
17099 const char *assignlweaponscriptlist(int32_t index, int32_t *list_size)
17100 {
17101 if(index<0)
17102 {
17103 *list_size = (int32_t)aslweaponscripts.size();
17104 return NULL;
17105 }
17106
17107 return aslweaponscripts[index].c_str();
17108 }
17109
17110 const char *assigneweaponscriptlist(int32_t index, int32_t *list_size)
17111 {
17112 if(index<0)
17113 {
17114 *list_size = (int32_t)aseweaponscripts.size();
17115 return NULL;
17116 }
17117
17118 return aseweaponscripts[index].c_str();
17119 }
17120
17121 const char *assignplayerscriptlist(int32_t index, int32_t *list_size)
17122 {
17123 if(index<0)
17124 {
17125 *list_size = (int32_t)asplayerscripts.size();
17126 return NULL;
17127 }
17128
17129 return asplayerscripts[index].c_str();
17130 }
17131
17132 const char *assigndmapscriptlist(int32_t index, int32_t *list_size)
17133 {
17134 if(index<0)
17135 {
17136 *list_size = (int32_t)asdmapscripts.size();
17137 return NULL;
17138 }
17139
17140 return asdmapscripts[index].c_str();
17141 }
17142
17143 const char *assignscreenscriptlist(int32_t index, int32_t *list_size)
17144 {
17145 if(index<0)
17146 {
17147 *list_size = (int32_t)asscreenscripts.size();
17148 return NULL;
17149 }
17150
17151 return asscreenscripts[index].c_str();
17152 }
17153
17154 const char *assignitemspritescriptlist(int32_t index, int32_t *list_size)
17155 {
17156 if(index<0)
17157 {
17158 *list_size = (int32_t)asitemspritescripts.size();
17159 return NULL;
17160 }
17161
17162 return asitemspritescripts[index].c_str();
17163 }
17164
17165 const char *assigncomboscriptlist(int32_t index, int32_t *list_size)
17166 {
17167 if(index<0)
17168 {
17169 *list_size = (int32_t)ascomboscripts.size();
17170 return NULL;
17171 }
17172
17173 return ascomboscripts[index].c_str();
17174 }
17175
17176 const char *assigngenericscriptlist(int32_t index, int32_t *list_size)
17177 {
17178 if(index<0)
17179 {
17180 *list_size = (int32_t)asgenericscripts.size();
17181 return NULL;
17182 }
17183
17184 return asgenericscripts[index].c_str();
17185 }
17186
17187 const char *assignsubscreenscriptlist(int32_t index, int32_t *list_size)
17188 {
17189 if(index<0)
17190 {
17191 *list_size = (int32_t)assubscreenscripts.size();
17192 return NULL;
17193 }
17194
17195 return assubscreenscripts[index].c_str();
17196 }
17197
17198 12 static ListData assignffc_list(assignffclist, &font);
17199 12 static ListData assignffcscript_list(assignffcscriptlist, &font);
17200 12 static ListData assignglobal_list(assigngloballist, &font);
17201 12 static ListData assignglobalscript_list(assignglobalscriptlist, &font);
17202 12 static ListData assignitem_list(assignitemlist, &font);
17203 12 static ListData assignitemscript_list(assignitemscriptlist, &font);
17204 12 static ListData assignnpc_list(assignnpclist, &font);
17205 12 static ListData assignnpcscript_list(assignnpcscriptlist, &font);
17206 12 static ListData assignlweapon_list(assignlweaponlist, &font);
17207 12 static ListData assignlweaponscript_list(assignlweaponscriptlist, &font);
17208 12 static ListData assigneweapon_list(assigneweaponlist, &font);
17209 12 static ListData assigneweaponscript_list(assigneweaponscriptlist, &font);
17210
17211 12 static ListData assignplayer_list(assignplayerlist, &font);
17212 12 static ListData assignplayerscript_list(assignplayerscriptlist, &font);
17213
17214 12 static ListData assigndmap_list(assigndmaplist, &font);
17215 12 static ListData assigndmapscript_list(assigndmapscriptlist, &font);
17216
17217 12 static ListData assignscreen_list(assignscreenlist, &font);
17218 12 static ListData assignscreenscript_list(assignscreenscriptlist, &font);
17219
17220 12 static ListData assignitemsprite_list(assignitemspritelist, &font);
17221 12 static ListData assignitemspritescript_list(assignitemspritescriptlist, &font);
17222
17223 12 static ListData assigncombo_list(assigncombolist, &font);
17224 12 static ListData assigncomboscript_list(assigncomboscriptlist, &font);
17225
17226 12 static ListData assigngeneric_list(assigngenericlist, &font);
17227 12 static ListData assigngenericscript_list(assigngenericscriptlist, &font);
17228
17229 12 static ListData assignsubscreen_list(assignsubscreenlist, &font);
17230 12 static ListData assignsubscreenscript_list(assignsubscreenscriptlist, &font);
17231
17232 static DIALOG assignscript_dlg[] =
17233 {
17234 // x y w h fg bg key flags d1 d2 dp
17235 12 { jwin_win_proc, 0, 0, 330, 236, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Assign Compiled Script", NULL, NULL },
17236 12 { jwin_tab_proc, 6, 25, 330-12, 130, 0, 0, 0, 0, 0, 0, assignscript_tabs, NULL, (void*)assignscript_dlg },
17237 12 { jwin_button_proc, 251, 207, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
17238 12 { jwin_button_proc, 182, 207, 61, 21, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
17239 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignffc_list, NULL, NULL },
17240 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignffcscript_list, NULL, NULL },
17241 //6
17242 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17243 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignglobal_list, NULL, NULL },
17244 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignglobalscript_list, NULL, NULL },
17245 //9
17246 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17247 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignitem_list, NULL, NULL },
17248 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignitemscript_list, NULL, NULL },
17249 //12
17250 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17251 //13
17252 12 { jwin_check_proc, 22, 211, 90, 8, vc(14), vc(1), 0, 0, 1, 0, (void *) "Output ZASM code to allegro.log", NULL, NULL },
17253 12 { jwin_text_proc, 22, 178, 90, 24, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
17254 12 { d_dummy_proc, 0, 0, 0, 0, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
17255 //16
17256 12 { d_dummy_proc, 0, 0, 0, 0, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
17257 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
17258 //npc scripts
17259 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignnpc_list, NULL, NULL },
17260 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignnpcscript_list, NULL, NULL },
17261 //20
17262 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17263 //21
17264 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignlweapon_list, NULL, NULL },
17265 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignlweaponscript_list, NULL, NULL },
17266 //23
17267 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17268 //24
17269 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigneweapon_list, NULL, NULL },
17270 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigneweaponscript_list, NULL, NULL },
17271 //26
17272 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17273 //27
17274 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignplayer_list, NULL, NULL },
17275 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignplayerscript_list, NULL, NULL },
17276 //29
17277 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17278 //30
17279 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignscreen_list, NULL, NULL },
17280 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignscreenscript_list, NULL, NULL },
17281 //32
17282 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17283 //33
17284 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigndmap_list, NULL, NULL },
17285 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigndmapscript_list, NULL, NULL },
17286 //35
17287 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17288 //36
17289 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignitemsprite_list, NULL, NULL },
17290 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignitemspritescript_list, NULL, NULL },
17291 //38
17292 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17293
17294 //39
17295 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigncombo_list, NULL, NULL },
17296 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigncomboscript_list, NULL, NULL },
17297 //41
17298 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17299 12 { jwin_button_proc, 78-24, 158, 48, 16, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Script Info", NULL, NULL },
17300 12 { jwin_button_proc, 174+78-24, 158, 48, 16, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Script Info", NULL, NULL },
17301 12 { jwin_button_proc, 87+78-24, 158, 48, 16, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Clear", NULL, NULL },
17302 //45
17303 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigngeneric_list, NULL, NULL },
17304 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigngenericscript_list, NULL, NULL },
17305 //47
17306 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17307 //48
17308 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignsubscreen_list, NULL, NULL },
17309 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignsubscreenscript_list, NULL, NULL },
17310 //50
17311 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17312 12 { jwin_check_proc, 22, 221, 90, 8, vc(14), vc(1), 0, 0, 1, 0, (void *) "...And output ZASM comments", NULL, NULL },
17313
17314 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
17315
17316 };
17317
17318 int32_t txtout(BITMAP* dest, const char* txt, int32_t x, int32_t y, bool disabled)
17319 {
17320 if(disabled)
17321 {
17322 gui_textout_ln(dest, font, (uint8_t*)txt, x+1, y+1, scheme[jcLIGHT], scheme[jcBOX], 0);
17323 return gui_textout_ln(dest, font, (uint8_t*)txt, x, y, scheme[jcMEDDARK], -1, 0);
17324 }
17325 else
17326 {
17327 return gui_textout_ln(dest, font, (uint8_t*)txt, x, y, scheme[jcBOXFG], scheme[jcBOX], 0);
17328 }
17329 }
17330
17331 int32_t jwin_zmeta_proc(int32_t msg, DIALOG *d, int32_t )
17332 {
17333 int32_t ret = D_O_K;
17334 ASSERT(d);
17335
17336 BITMAP* target = (msg==MSG_START ? NULL : screen);
17337 switch(msg)
17338 {
17339 case MSG_START:
17340 case MSG_DRAW:
17341 {
17342 FONT *oldfont = font;
17343
17344 if(d->dp2)
17345 {
17346 font = (FONT*)d->dp2;
17347 }
17348
17349 bool disabled = (d->flags & D_DISABLED) != 0;
17350 if(d->dp)
17351 {
17352 zasm_meta const& meta = *((zasm_meta*)d->dp);
17353 int32_t ind = -1;
17354 d->w = 0;
17355 if(!meta.valid())
17356 {
17357 d->w = txtout(target, "Invalid ZASM metadata found!", d->x, d->y, disabled);
17358 ++ind;
17359 }
17360
17361 int32_t t_w = 0;
17362 char buf[1024];
17363 memset(buf, 0, sizeof(buf));
17364 sprintf(buf, "ZASM Version: %d", meta.zasm_v);
17365 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17366 d->w = zc_max(d->w, t_w);
17367 memset(buf, 0, sizeof(buf));
17368 sprintf(buf, "Metadata Version: %d", meta.meta_v);
17369 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17370 d->w = zc_max(d->w, t_w);
17371 memset(buf, 0, sizeof(buf));
17372 sprintf(buf, "FFScript Version: %d", meta.ffscript_v);
17373 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17374 d->w = zc_max(d->w, t_w);
17375 memset(buf, 0, sizeof(buf));
17376 sprintf(buf, "Script Name: %s", meta.script_name.c_str());
17377 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17378 d->w = zc_max(d->w, t_w);
17379 memset(buf, 0, sizeof(buf));
17380 sprintf(buf, "Author: %s", meta.author.c_str());
17381 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17382 d->w = zc_max(d->w, t_w);
17383 memset(buf, 0, sizeof(buf));
17384 sprintf(buf, "Script Type: %s", get_script_name(meta.script_type).c_str());
17385 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17386 d->w = zc_max(d->w, t_w);
17387 for(auto q = 0; q < NUM_ZMETA_ATTRIBUTES; ++q)
17388 {
17389 if(!meta.attributes[q].size())
17390 continue;
17391 memset(buf, 0, sizeof(buf));
17392 sprintf(buf, "Attributes[%d]: %s", q, meta.attributes[q].c_str());
17393 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17394 d->w = zc_max(d->w, t_w);
17395 }
17396 bool indentrun = false;
17397 int32_t run_indent = txtout(NULL, "void run(", 0, 0, false);
17398 std::ostringstream oss;
17399 oss << "void run(";
17400 for(int32_t q = 0; q < 8; ++q)
17401 {
17402 if(!meta.run_idens[q].size() || meta.run_types[q] == ZMETA_NULL_TYPE) continue;
17403 if(q > 0)
17404 oss << ", ";
17405 string type_name = ZScript::getDataTypeName(meta.run_types[q]);
17406 lowerstr(type_name); //all lowercase for this output
17407 if(oss.str().size() > unsigned(indentrun ? 41 : 50))
17408 {
17409 memset(buf, 0, sizeof(buf));
17410 sprintf(buf, "%s", oss.str().c_str());
17411 t_w = txtout(target, buf, d->x + (indentrun ? run_indent : 0), d->y + ((++ind)*(text_height(font) + 3)), disabled) + (indentrun ? run_indent : 0);
17412 d->w = zc_max(d->w, t_w);
17413 oss.str("");
17414 indentrun = true;
17415 }
17416 oss << type_name.c_str() << " " << meta.run_idens[q];
17417 }
17418 oss << ");";
17419 memset(buf, 0, sizeof(buf));
17420 sprintf(buf, "%s", oss.str().c_str());
17421 t_w = txtout(target, buf, d->x + (indentrun ? run_indent : 0), d->y + ((++ind)*(text_height(font) + 3)), disabled) + (indentrun ? run_indent : 0);
17422 d->w = zc_max(d->w, t_w);
17423 memset(buf, 0, sizeof(buf));
17424 sprintf(buf, "Compiler Version: %d.%d.%d.%d", meta.compiler_v1, meta.compiler_v2, meta.compiler_v3, meta.compiler_v4);
17425 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17426 d->w = zc_max(d->w, t_w);
17427 memset(buf, 0, sizeof(buf));
17428 sprintf(buf, "Parser-generated: %s", (meta.flags & ZMETA_AUTOGEN)!=0 ? "TRUE" : "FALSE");
17429 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17430 d->w = zc_max(d->w, t_w);
17431 d->h = (++ind) * (text_height(font) + 3) -3;
17432 }
17433 else
17434 {
17435 d->w = txtout(target, "No ZASM metadata found!", d->x, d->y, disabled);
17436 d->h = text_height(font);
17437 }
17438
17439 if(d->dp3) //function trigger
17440 {
17441 typedef void (*funcType)(void);
17442 funcType func=reinterpret_cast<funcType>(d->dp3);
17443 func();
17444 }
17445
17446 font = oldfont;
17447 break;
17448 }
17449 }
17450
17451 return ret;
17452 }
17453
17454 void resize_scriptinfo_dlg();
17455
17456 static DIALOG scriptinfo_dlg[] =
17457 {
17458 // x y w h fg bg key flags d1 d2 dp
17459 { jwin_win_proc, 0, 0, 200, 150, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Script Metadata", NULL, NULL },
17460 { d_dummy_proc, 6, 25, 330-12, 130, 0, 0, 0, 0, 0, 0, assignscript_tabs, NULL, NULL },
17461 { jwin_button_proc, 70, 120, 60, 20, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "Done", NULL, NULL },
17462 { jwin_zmeta_proc, 50, 30, 100, 100, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, (void*)resize_scriptinfo_dlg },
17463
17464 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
17465 };
17466
17467 void resize_scriptinfo_dlg()
17468 {
17469 DIALOG *meta_proc = &scriptinfo_dlg[3], *window = &scriptinfo_dlg[0], *ok_button = &scriptinfo_dlg[2];
17470 int32_t bmargin = 15, hmargins = 30;
17471 jwin_ulalign_dialog(scriptinfo_dlg);
17472 window->w = hmargins*2 + meta_proc->w;
17473 meta_proc->x = hmargins;
17474 window->h = meta_proc->y + meta_proc->h + ok_button->h + bmargin*2;
17475 ok_button->x = (window->w/2)-(ok_button->w/2);
17476 ok_button->y = meta_proc->y + meta_proc->h + bmargin;
17477 jwin_center_dialog(scriptinfo_dlg);
17478 }
17479
17480 void showScriptInfo(zasm_meta const* meta)
17481 {
17482 scriptinfo_dlg[3].dp = (void*)meta;
17483 scriptinfo_dlg[0].dp2 = get_zc_font(font_lfont);
17484 large_dialog(scriptinfo_dlg);
17485 jwin_zmeta_proc(MSG_START,&scriptinfo_dlg[3],0); //Calculate size before calling dialog
17486 jwin_center_dialog(scriptinfo_dlg);
17487 do_zqdialog(scriptinfo_dlg,2);
17488 }
17489
17490 void write_includepaths();
17491 void call_compile_settings();
17492 int32_t onZScriptCompilerSettings()
17493 {
17494 call_compile_settings();
17495 return D_O_K;
17496 }
17497
17498 void doEditZScript()
17499 {
17500 if(do_box_edit(zScript, "ZScript Buffer", false, false))
17501 mark_save_dirty();
17502 }
17503
17504 std::string qst_cfg_header_from_path(std::string path);
17505 extern char *filepath;
17506 string get_box_cfg_hdr(int num)
17507 {
17508 if(num)
17509 return "misc";
17510 return qst_cfg_header_from_path(filepath);
17511 }
17512
17513 6 void clear_map_states()
17514 {
17515
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(map<int32_t, script_slot_data>::iterator it = ffcmap.begin();
17516 3072 it != ffcmap.end(); ++it)
17517 {
17518 3066 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17519 3066 }
17520
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 6 times.
54 for(map<int32_t, script_slot_data>::iterator it = globalmap.begin();
17521 54 it != globalmap.end(); ++it)
17522 {
17523 48 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17524 48 }
17525
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = itemmap.begin();
17526 1536 it != itemmap.end(); ++it)
17527 {
17528 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17529 1530 }
17530
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = npcmap.begin();
17531 1536 it != npcmap.end(); ++it)
17532 {
17533 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17534 1530 }
17535
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = ewpnmap.begin();
17536 1536 it != ewpnmap.end(); ++it)
17537 {
17538 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17539 1530 }
17540
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = lwpnmap.begin();
17541 1536 it != lwpnmap.end(); ++it)
17542 {
17543 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17544 1530 }
17545
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 for(map<int32_t, script_slot_data>::iterator it = playermap.begin();
17546 30 it != playermap.end(); ++it)
17547 {
17548 24 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17549 24 }
17550
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = dmapmap.begin();
17551 1536 it != dmapmap.end(); ++it)
17552 {
17553 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17554 1530 }
17555
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = screenmap.begin();
17556 1536 it != screenmap.end(); ++it)
17557 {
17558 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17559 1530 }
17560
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = itemspritemap.begin();
17561 1536 it != itemspritemap.end(); ++it)
17562 {
17563 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17564 1530 }
17565
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(map<int32_t, script_slot_data>::iterator it = comboscriptmap.begin();
17566 3072 it != comboscriptmap.end(); ++it)
17567 {
17568 3066 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17569 3066 }
17570 6 }
17571
17572 void clearAssignSlotDlg()
17573 {
17574 assignscript_dlg[0].dp2 = get_zc_font(font_lfont);
17575 assignscript_dlg[4].d1 = -1;
17576 assignscript_dlg[5].d1 = -1;
17577 assignscript_dlg[7].d1 = -1;
17578 assignscript_dlg[8].d1 = -1;
17579 assignscript_dlg[10].d1 = -1;
17580 assignscript_dlg[11].d1 = -1;
17581 assignscript_dlg[13].flags = 0;
17582 }
17583
17584 void inc_script_name(string& name)
17585 {
17586 size_t pos = name.find_last_not_of("0123456789");
17587 pos = name.find_first_of("0123456789",pos);
17588 std::ostringstream oss;
17589 if(pos == string::npos)
17590 {
17591 oss << name << 2;
17592 }
17593 else
17594 {
17595 int32_t val = atoi(name.substr(pos).c_str());
17596 oss << name.substr(0,pos) << val+1;
17597 }
17598 name = oss.str();
17599 }
17600
17601 enum script_slot_type
17602 {
17603 type_ffc, type_global, type_itemdata, type_npc, type_lweapon, type_eweapon,
17604 type_hero, type_dmap, type_screen, type_itemsprite, type_combo, type_generic,
17605 type_subscreen, num_types
17606 };
17607 script_slot_type getType(ScriptType type)
17608 {
17609 switch(type)
17610 {
17611 case ScriptType::FFC: return type_ffc;
17612 case ScriptType::Global: return type_global;
17613 case ScriptType::Item: return type_itemdata;
17614 case ScriptType::NPC: return type_npc;
17615 case ScriptType::Lwpn: return type_lweapon;
17616 case ScriptType::Ewpn: return type_eweapon;
17617 case ScriptType::Hero: return type_hero;
17618 case ScriptType::DMap:
17619 case ScriptType::ScriptedActiveSubscreen:
17620 case ScriptType::ScriptedPassiveSubscreen:
17621 case ScriptType::OnMap:
17622 return type_dmap;
17623 case ScriptType::Generic: case ScriptType::GenericFrozen:
17624 return type_generic;
17625 case ScriptType::Screen: return type_screen;
17626 case ScriptType::ItemSprite: return type_itemsprite;
17627 case ScriptType::Combo: return type_combo;
17628 case ScriptType::EngineSubscreen: return type_subscreen;
17629 default: return type_ffc; //Default
17630 }
17631 }
17632 #define SLOTMSGFLAG_MISSING 0x01
17633 #define SLOTMSG_SIZE 512
17634 bool checkSkip(int32_t format, byte flags)
17635 {
17636 switch(format)
17637 {
17638 case SCRIPT_FORMAT_DEFAULT:
17639 return (flags != 0);
17640 case SCRIPT_FORMAT_INVALID:
17641 return ((flags & SLOTMSGFLAG_MISSING)==0);
17642 default: return true;
17643 }
17644 }
17645 void clearAllSlots(int32_t type, byte flags = 0)
17646 {
17647 bound(type,0,num_types-1);
17648 switch(type)
17649 {
17650 case type_ffc:
17651 {
17652 for(int32_t q = 0; q < NUMSCRIPTFFC-1; ++q)
17653 {
17654 if(checkSkip(ffcmap[q].format, flags)) continue;
17655 ffcmap[q].scriptname = "";
17656 ffcmap[q].format = SCRIPT_FORMAT_DEFAULT;
17657 }
17658 break;
17659 }
17660 case type_global:
17661 {
17662 //Start at 1 to not clear Init
17663 for(int32_t q = 1; q < NUMSCRIPTGLOBAL; ++q)
17664 {
17665 if(checkSkip(globalmap[q].format, flags)) continue;
17666 globalmap[q].scriptname = "";
17667 globalmap[q].format = SCRIPT_FORMAT_DEFAULT;
17668 }
17669 break;
17670 }
17671 case type_itemdata:
17672 {
17673 for(int32_t q = 0; q < NUMSCRIPTITEM-1; ++q)
17674 {
17675 if(checkSkip(itemmap[q].format, flags)) continue;
17676 itemmap[q].scriptname = "";
17677 itemmap[q].format = SCRIPT_FORMAT_DEFAULT;
17678 }
17679 break;
17680 }
17681 case type_npc:
17682 {
17683 for(int32_t q = 0; q < NUMSCRIPTGUYS-1; ++q)
17684 {
17685 if(checkSkip(npcmap[q].format, flags)) continue;
17686 npcmap[q].scriptname = "";
17687 npcmap[q].format = SCRIPT_FORMAT_DEFAULT;
17688 }
17689 break;
17690 }
17691 case type_lweapon:
17692 {
17693 for(int32_t q = 0; q < NUMSCRIPTWEAPONS-1; ++q)
17694 {
17695 if(checkSkip(lwpnmap[q].format, flags)) continue;
17696 lwpnmap[q].scriptname = "";
17697 lwpnmap[q].format = SCRIPT_FORMAT_DEFAULT;
17698 }
17699 break;
17700 }
17701 case type_eweapon:
17702 {
17703 for(int32_t q = 0; q < NUMSCRIPTWEAPONS-1; ++q)
17704 {
17705 if(checkSkip(ewpnmap[q].format, flags)) continue;
17706 ewpnmap[q].scriptname = "";
17707 ewpnmap[q].format = SCRIPT_FORMAT_DEFAULT;
17708 }
17709 break;
17710 }
17711 case type_hero:
17712 {
17713 for(int32_t q = 0; q < NUMSCRIPTHERO-1; ++q)
17714 {
17715 if(checkSkip(playermap[q].format, flags)) continue;
17716 playermap[q].scriptname = "";
17717 playermap[q].format = SCRIPT_FORMAT_DEFAULT;
17718 }
17719 break;
17720 }
17721 case type_dmap:
17722 {
17723 for(int32_t q = 0; q < NUMSCRIPTSDMAP-1; ++q)
17724 {
17725 if(checkSkip(dmapmap[q].format, flags)) continue;
17726 dmapmap[q].scriptname = "";
17727 dmapmap[q].format = SCRIPT_FORMAT_DEFAULT;
17728 }
17729 break;
17730 }
17731 case type_screen:
17732 {
17733 for(int32_t q = 0; q < NUMSCRIPTSCREEN-1; ++q)
17734 {
17735 if(checkSkip(screenmap[q].format, flags)) continue;
17736 screenmap[q].scriptname = "";
17737 screenmap[q].format = SCRIPT_FORMAT_DEFAULT;
17738 }
17739 break;
17740 }
17741 case type_itemsprite:
17742 {
17743 for(int32_t q = 0; q < NUMSCRIPTSITEMSPRITE-1; ++q)
17744 {
17745 if(checkSkip(itemspritemap[q].format, flags)) continue;
17746 itemspritemap[q].scriptname = "";
17747 itemspritemap[q].format = SCRIPT_FORMAT_DEFAULT;
17748 }
17749 break;
17750 }
17751 case type_combo:
17752 {
17753 for(int32_t q = 0; q < NUMSCRIPTSCOMBODATA-1; ++q)
17754 {
17755 if(checkSkip(comboscriptmap[q].format, flags)) continue;
17756 comboscriptmap[q].scriptname = "";
17757 comboscriptmap[q].format = SCRIPT_FORMAT_DEFAULT;
17758 }
17759 break;
17760 }
17761 case type_generic:
17762 {
17763 for(int32_t q = 0; q < NUMSCRIPTSGENERIC-1; ++q)
17764 {
17765 if(checkSkip(genericmap[q].format, flags)) continue;
17766 genericmap[q].scriptname = "";
17767 genericmap[q].format = SCRIPT_FORMAT_DEFAULT;
17768 }
17769 break;
17770 }
17771 case type_subscreen:
17772 {
17773 for(int32_t q = 0; q < NUMSCRIPTSSUBSCREEN-1; ++q)
17774 {
17775 if(checkSkip(subscreenmap[q].format, flags)) continue;
17776 subscreenmap[q].scriptname = "";
17777 subscreenmap[q].format = SCRIPT_FORMAT_DEFAULT;
17778 }
17779 break;
17780 }
17781 }
17782 }
17783
17784 static bool doslots_log_output = false, doslots_comment_output = true;
17785 6 void setup_scriptslot_dlg(char* buf, byte flags)
17786 {
17787 //{ Set up the textbox at the bottom, and auto-resize height based on it
17788 6 int32_t prev_height = assignscript_dlg[14].h;
17789 6 memset(buf, 0, SLOTMSG_SIZE);
17790 //
17791 6 strcpy(buf, "Slots with matching names have been updated.\n");
17792
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if(flags & SLOTMSGFLAG_MISSING)
17793 3 strcat(buf,"Scripts prefixed with '--' were not found, and will not function.\n");
17794 6 strcat(buf,"Global scripts named 'Init' will be appended to '~Init'");
17795 //
17796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 SETFLAG(assignscript_dlg[13].flags, D_SELECTED, doslots_log_output);
17797
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 SETFLAG(assignscript_dlg[51].flags, D_SELECTED, doslots_comment_output);
17798 6 assignscript_dlg[14].dp = buf;
17799 6 object_message(&assignscript_dlg[14], MSG_START, 0); //Set the width/height
17800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(int32_t diff = assignscript_dlg[14].h - prev_height) //resize dlg
17801 {
17802 6 int32_t prev_bottom = assignscript_dlg[14].y + prev_height;
17803
2/2
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 6 times.
312 for(int32_t q = 1; assignscript_dlg[q].proc; ++q)
17804 {
17805
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 300 times.
306 if(q==14) continue; //Don't change self
17806
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 24 times.
300 if(assignscript_dlg[q].y < prev_bottom) continue; //above proc
17807 24 assignscript_dlg[q].y += diff;
17808 24 }
17809 6 assignscript_dlg[0].h += diff;
17810 6 jwin_center_dialog(assignscript_dlg);
17811 6 }
17812 //}
17813 6 }
17814
17815 std::string global_slotnames[NUMSCRIPTGLOBAL] = {
17816 "Init",
17817 "Active",
17818 "onExit",
17819 "onSaveLoad",
17820 "onLaunch",
17821 "onContGame",
17822 "onF6Menu",
17823 "onSave",
17824 };
17825 std::string player_slotnames[NUMSCRIPTHERO-1] = {
17826 "Init",
17827 "Active",
17828 "onDeath",
17829 "onWin",
17830 };
17831 6 byte reload_scripts(map<string, disassembled_script_data> &scripts)
17832 {
17833 6 byte slotflags = 0;
17834 char temp[100];
17835
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(int32_t i = 0; i < NUMSCRIPTFFC-1; i++)
17836 {
17837
2/2
✓ Branch 0 taken 2987 times.
✓ Branch 1 taken 79 times.
3066 if(ffcmap[i].isEmpty())
17838 2987 sprintf(temp, "Slot %d:", i+1);
17839 else
17840 {
17841 79 sprintf(temp, "Slot %d:", i+1);
17842
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 6 times.
79 if(scripts.find(ffcmap[i].scriptname) != scripts.end())
17843 73 ffcmap[i].format = SCRIPT_FORMAT_DEFAULT;
17844 else // Previously loaded script not found
17845 {
17846 6 ffcmap[i].format = SCRIPT_FORMAT_INVALID;
17847 6 slotflags |= SLOTMSGFLAG_MISSING;
17848 }
17849 }
17850 3066 ffcmap[i].slotname = temp;
17851 3066 ffcmap[i].update();
17852 3066 }
17853
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 6 times.
54 for(int32_t i = 0; i < NUMSCRIPTGLOBAL; i++)
17854 {
17855
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 globalmap[i].slotname=fmt::format("{}:",global_slotnames[i]);
17856
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 11 times.
48 if(!globalmap[i].isEmpty())
17857 {
17858
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 if(scripts.find(globalmap[i].scriptname) != scripts.end() || globalmap[i].scriptname == "~Init")
17859 11 globalmap[i].format = SCRIPT_FORMAT_DEFAULT;
17860 else // Unloaded
17861 {
17862 globalmap[i].format = SCRIPT_FORMAT_INVALID;
17863 slotflags |= SLOTMSGFLAG_MISSING;
17864 }
17865 11 }
17866 48 globalmap[i].update();
17867 48 }
17868
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTITEM-1; i++)
17869 {
17870
2/2
✓ Branch 0 taken 1517 times.
✓ Branch 1 taken 13 times.
1530 if(itemmap[i].isEmpty())
17871 1517 sprintf(temp, "Slot %d:", i+1);
17872 else
17873 {
17874 13 sprintf(temp, "Slot %d:", i+1);
17875
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if(scripts.find(itemmap[i].scriptname) != scripts.end())
17876 13 itemmap[i].format = SCRIPT_FORMAT_DEFAULT;
17877 else // Previously loaded script not found
17878 {
17879 itemmap[i].format = SCRIPT_FORMAT_INVALID;
17880 slotflags |= SLOTMSGFLAG_MISSING;
17881 }
17882 }
17883 1530 itemmap[i].slotname = temp;
17884 1530 itemmap[i].update();
17885 1530 }
17886
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTGUYS-1; i++)
17887 {
17888
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 if(npcmap[i].isEmpty())
17889 1530 sprintf(temp, "Slot %d:", i+1);
17890 else
17891 {
17892 sprintf(temp, "Slot %d:", i+1);
17893 if(scripts.find(npcmap[i].scriptname) != scripts.end())
17894 npcmap[i].format = SCRIPT_FORMAT_DEFAULT;
17895 else // Previously loaded script not found
17896 {
17897 npcmap[i].format = SCRIPT_FORMAT_INVALID;
17898 slotflags |= SLOTMSGFLAG_MISSING;
17899 }
17900 }
17901 1530 npcmap[i].slotname = temp;
17902 1530 npcmap[i].update();
17903 1530 }
17904
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTWEAPONS-1; i++)
17905 {
17906
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 if(ewpnmap[i].isEmpty())
17907 1530 sprintf(temp, "Slot %d:", i+1);
17908 else
17909 {
17910 sprintf(temp, "Slot %d:", i+1);
17911 if(scripts.find(ewpnmap[i].scriptname) != scripts.end())
17912 ewpnmap[i].format = SCRIPT_FORMAT_DEFAULT;
17913 else // Previously loaded script not found
17914 {
17915 ewpnmap[i].format = SCRIPT_FORMAT_INVALID;
17916 slotflags |= SLOTMSGFLAG_MISSING;
17917 }
17918 }
17919 1530 ewpnmap[i].slotname = temp;
17920 1530 ewpnmap[i].update();
17921 1530 }
17922
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTWEAPONS-1; i++)
17923 {
17924
2/2
✓ Branch 0 taken 1529 times.
✓ Branch 1 taken 1 times.
1530 if(lwpnmap[i].isEmpty())
17925 1529 sprintf(temp, "Slot %d:", i+1);
17926 else
17927 {
17928 1 sprintf(temp, "Slot %d:", i+1);
17929
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(scripts.find(lwpnmap[i].scriptname) != scripts.end())
17930 1 lwpnmap[i].format = SCRIPT_FORMAT_DEFAULT;
17931 else // Previously loaded script not found
17932 {
17933 lwpnmap[i].format = SCRIPT_FORMAT_INVALID;
17934 slotflags |= SLOTMSGFLAG_MISSING;
17935 }
17936 }
17937 1530 lwpnmap[i].slotname = temp;
17938 1530 lwpnmap[i].update();
17939 1530 }
17940
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 for(int32_t i = 0; i < NUMSCRIPTHERO-1; i++)
17941 {
17942
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 playermap[i].slotname=fmt::format("{}:",player_slotnames[i]);
17943
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if(!playermap[i].isEmpty())
17944 {
17945 if(scripts.find(playermap[i].scriptname) != scripts.end())
17946 playermap[i].format = SCRIPT_FORMAT_DEFAULT;
17947 else // Unloaded
17948 {
17949 playermap[i].format = SCRIPT_FORMAT_INVALID;
17950 slotflags |= SLOTMSGFLAG_MISSING;
17951 }
17952 }
17953 24 playermap[i].update();
17954 24 }
17955
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTSCREEN-1; i++)
17956 {
17957
2/2
✓ Branch 0 taken 1528 times.
✓ Branch 1 taken 2 times.
1530 if(screenmap[i].isEmpty())
17958 1528 sprintf(temp, "Slot %d:", i+1);
17959 else
17960 {
17961 2 sprintf(temp, "Slot %d:", i+1);
17962
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(scripts.find(screenmap[i].scriptname) != scripts.end())
17963 2 screenmap[i].format = SCRIPT_FORMAT_DEFAULT;
17964 else // Previously loaded script not found
17965 {
17966 screenmap[i].format = SCRIPT_FORMAT_INVALID;
17967 slotflags |= SLOTMSGFLAG_MISSING;
17968 }
17969 }
17970 1530 screenmap[i].slotname = temp;
17971 1530 screenmap[i].update();
17972 1530 }
17973
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTSDMAP-1; i++)
17974 {
17975
2/2
✓ Branch 0 taken 1525 times.
✓ Branch 1 taken 5 times.
1530 if(dmapmap[i].isEmpty())
17976 1525 sprintf(temp, "Slot %d:", i+1);
17977 else
17978 {
17979 5 sprintf(temp, "Slot %d:", i+1);
17980
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(scripts.find(dmapmap[i].scriptname) != scripts.end())
17981 5 dmapmap[i].format = SCRIPT_FORMAT_DEFAULT;
17982 else // Previously loaded script not found
17983 {
17984 dmapmap[i].format = SCRIPT_FORMAT_INVALID;
17985 slotflags |= SLOTMSGFLAG_MISSING;
17986 }
17987 }
17988 1530 dmapmap[i].slotname = temp;
17989 1530 dmapmap[i].update();
17990 1530 }
17991
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTSITEMSPRITE-1; i++)
17992 {
17993
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 if(itemspritemap[i].isEmpty())
17994 1530 sprintf(temp, "Slot %d:", i+1);
17995 else
17996 {
17997 sprintf(temp, "Slot %d:", i+1);
17998 if(scripts.find(itemspritemap[i].scriptname) != scripts.end())
17999 itemspritemap[i].format = SCRIPT_FORMAT_DEFAULT;
18000 else // Previously loaded script not found
18001 {
18002 itemspritemap[i].format = SCRIPT_FORMAT_INVALID;
18003 slotflags |= SLOTMSGFLAG_MISSING;
18004 }
18005 }
18006 1530 itemspritemap[i].slotname = temp;
18007 1530 itemspritemap[i].update();
18008 1530 }
18009
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(int32_t i = 0; i < NUMSCRIPTSCOMBODATA-1; i++)
18010 {
18011
1/2
✓ Branch 0 taken 3066 times.
✗ Branch 1 not taken.
3066 if(comboscriptmap[i].isEmpty())
18012 3066 sprintf(temp, "Slot %d:", i+1);
18013 else
18014 {
18015 sprintf(temp, "Slot %d:", i+1);
18016 if(scripts.find(comboscriptmap[i].scriptname) != scripts.end())
18017 comboscriptmap[i].format = SCRIPT_FORMAT_DEFAULT;
18018 else // Previously loaded script not found
18019 {
18020 comboscriptmap[i].format = SCRIPT_FORMAT_INVALID;
18021 slotflags |= SLOTMSGFLAG_MISSING;
18022 }
18023 }
18024 3066 comboscriptmap[i].slotname = temp;
18025 3066 comboscriptmap[i].update();
18026 3066 }
18027
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(int32_t i = 0; i < NUMSCRIPTSGENERIC-1; i++)
18028 {
18029
2/2
✓ Branch 0 taken 3044 times.
✓ Branch 1 taken 22 times.
3066 if(genericmap[i].isEmpty())
18030 3044 sprintf(temp, "Slot %d:", i+1);
18031 else
18032 {
18033 22 sprintf(temp, "Slot %d:", i+1);
18034
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 times.
22 if(scripts.find(genericmap[i].scriptname) != scripts.end())
18035 21 genericmap[i].format = SCRIPT_FORMAT_DEFAULT;
18036 else // Previously loaded script not found
18037 {
18038 1 genericmap[i].format = SCRIPT_FORMAT_INVALID;
18039 1 slotflags |= SLOTMSGFLAG_MISSING;
18040 }
18041 }
18042 3066 genericmap[i].slotname = temp;
18043 3066 genericmap[i].update();
18044 3066 }
18045
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTSSUBSCREEN-1; i++)
18046 {
18047
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 if(subscreenmap[i].isEmpty())
18048 1530 sprintf(temp, "Slot %d:", i+1);
18049 else
18050 {
18051 sprintf(temp, "Slot %d:", i+1);
18052 if(scripts.find(subscreenmap[i].scriptname) != scripts.end())
18053 subscreenmap[i].format = SCRIPT_FORMAT_DEFAULT;
18054 else // Previously loaded script not found
18055 {
18056 subscreenmap[i].format = SCRIPT_FORMAT_INVALID;
18057 slotflags |= SLOTMSGFLAG_MISSING;
18058 }
18059 }
18060 1530 subscreenmap[i].slotname = temp;
18061 1530 subscreenmap[i].update();
18062 1530 }
18063 6 return slotflags;
18064 }
18065
18066 void doClearSlots(byte* flags);
18067
18068 static map<string, disassembled_script_data> *doslot_scripts = nullptr;
18069 21510 bool handle_slot(script_slot_data& slotdata, script_data* scriptdata)
18070 {
18071
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 21384 times.
21510 if(slotdata.hasScriptData())
18072 {
18073 126 auto& data = (*doslot_scripts)[slotdata.scriptname];
18074 126 scriptdata->meta = data.meta;
18075 126 scriptdata->pc = data.pc;
18076 126 scriptdata->end_pc = data.end_pc;
18077 126 scriptdata->zasm_script = zasm_scripts[0];
18078 126 }
18079
1/2
✓ Branch 0 taken 21384 times.
✗ Branch 1 not taken.
21384 else if(scriptdata)
18080 {
18081 21384 scriptdata->zasm_script = nullptr;
18082 21384 scriptdata->meta.zero();
18083 21384 scriptdata->pc = 0;
18084 21384 scriptdata->end_pc = 0;
18085 21384 }
18086 21510 return true;
18087 }
18088 78 bool handle_slot_map(map<int32_t, script_slot_data>& mp, int offs, script_data** scriptdata)
18089 {
18090
2/2
✓ Branch 0 taken 21510 times.
✓ Branch 1 taken 78 times.
21588 for(auto it = mp.begin(); it != mp.end(); it++)
18091 {
18092
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21510 times.
21510 if(!handle_slot(it->second, scriptdata[it->first + offs]))
18093 return false;
18094 21510 }
18095 78 return true;
18096 78 }
18097
18098 void smart_slot_named(map<string, disassembled_script_data> &scripts,
18099 vector<string> const& scriptnames, map<int32_t, script_slot_data>& mp,
18100 std::string* slotnames, int slotstart, int slotend)
18101 {
18102 for(int q = slotstart; q < slotend; ++q)
18103 {
18104 auto& lval = mp[q];
18105 if(!lval.isEmpty())
18106 continue; //occupied, leave alone
18107 bool done = false;
18108 if(!done) //Check case-sensitive
18109 for(size_t rind = 0; rind < scriptnames.size(); ++rind)
18110 {
18111 auto const& rval = scriptnames[rind];
18112 if(rval == "<none>") continue;
18113 if(rval == slotnames[q])
18114 { //Perfect match
18115 lval.updateName(rval);
18116 lval.format = scripts[lval.scriptname].format;
18117 done = true;
18118 break;
18119 }
18120 }
18121 if(!done) //Check case-insensitive
18122 for(size_t rind = 0; rind < scriptnames.size(); ++rind)
18123 {
18124 auto const& rval = scriptnames[rind];
18125 if(rval == "<none>") continue;
18126 string lc_rv = rval, lc_slot = slotnames[q];
18127 lowerstr(lc_rv);
18128 lowerstr(lc_slot);
18129 if(lc_rv == lc_slot)
18130 { //Insensitive match
18131 lval.updateName(rval);
18132 lval.format = scripts[lval.scriptname].format;
18133 break;
18134 }
18135 }
18136 }
18137 }
18138 void smart_slot_type(map<string, disassembled_script_data> &scripts,
18139 vector<string> const& scriptnames, map<int32_t, script_slot_data>& mp,
18140 int slotcount)
18141 {
18142 for(size_t rind = 0; rind < scriptnames.size(); ++rind)
18143 {
18144 auto const& rval = scriptnames[rind];
18145 if(rval == "<none>") continue;
18146 script_slot_data* first_open_slot = nullptr;
18147 bool done = false;
18148 for(int q = 0; q < slotcount; ++q)
18149 {
18150 auto& lval = mp[q];
18151 if(lval.isEmpty())
18152 {
18153 if(!first_open_slot)
18154 first_open_slot = &lval;
18155 }
18156 else if(lval.scriptname == rval)
18157 {
18158 done = true;
18159 break;
18160 }
18161 }
18162 if(!done)
18163 {
18164 if(!first_open_slot)
18165 break; //no slots left to assign to!
18166 first_open_slot->updateName(rval);
18167 first_open_slot->format = scripts[first_open_slot->scriptname].format;
18168 }
18169 }
18170 }
18171
18172 6 bool do_slots(vector<shared_ptr<ZScript::Opcode>> const& zasm,
18173 map<string, disassembled_script_data> &scripts, int assign_mode)
18174 {
18175 6 large_dialog(assignscript_dlg);
18176 6 int32_t ret = 3;
18177 6 char slots_msg[SLOTMSG_SIZE] = {0};
18178 6 byte slotflags = reload_scripts(scripts);
18179 6 setup_scriptslot_dlg(slots_msg, slotflags);
18180 6 bool retval = false;
18181
18182 6 popup_zqdialog_start();
18183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 while(!assign_mode)
18184 {
18185 slotflags = reload_scripts(scripts);
18186 ret = do_zqdialog(assignscript_dlg, ret);
18187
18188 switch(ret)
18189 {
18190 case 0:
18191 case 2:
18192 //Cancel
18193 goto exit_do_slots;
18194
18195 case 3: goto auto_do_slots;
18196
18197 case 6:
18198 //<<, FFC
18199 {
18200 int32_t lind = assignscript_dlg[4].d1;
18201 int32_t rind = assignscript_dlg[5].d1;
18202
18203 if(lind < 0 || rind < 0)
18204 break;
18205
18206 if(asffcscripts[rind] == "<none>")
18207 {
18208 ffcmap[lind].scriptname = "";
18209 ffcmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18210 }
18211 else
18212 {
18213 ffcmap[lind].updateName(asffcscripts[rind]);
18214 ffcmap[lind].format = scripts[ffcmap[lind].scriptname].format;
18215 }
18216
18217 break;
18218 }
18219 case 9:
18220 //<<, Global
18221 {
18222 int32_t lind = assignscript_dlg[7].d1;
18223 int32_t rind = assignscript_dlg[8].d1;
18224
18225 if(lind < 0 || rind < 0)
18226 break;
18227
18228 if(lind == 0)
18229 {
18230 displayinfo("Error","ZScript reserves this slot.");
18231 break;
18232 }
18233
18234 if(asglobalscripts[rind] == "<none>")
18235 {
18236 globalmap[lind].scriptname = "";
18237 globalmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18238 }
18239 else
18240 {
18241 globalmap[lind].updateName(asglobalscripts[rind]);
18242 globalmap[lind].format = scripts[globalmap[lind].scriptname].format;
18243 }
18244
18245 break;
18246 }
18247 case 12:
18248 //<<, ITEM
18249 {
18250 int32_t lind = assignscript_dlg[10].d1;
18251 int32_t rind = assignscript_dlg[11].d1;
18252
18253 if(lind < 0 || rind < 0)
18254 break;
18255
18256 if(asitemscripts[rind] == "<none>")
18257 {
18258 itemmap[lind].scriptname = "";
18259 itemmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18260 }
18261 else
18262 {
18263 itemmap[lind].updateName(asitemscripts[rind]);
18264 itemmap[lind].format = scripts[itemmap[lind].scriptname].format;
18265 }
18266
18267 break;
18268 }
18269 case 20:
18270 //<<, NPC
18271 {
18272 int32_t lind = assignscript_dlg[18].d1;
18273 int32_t rind = assignscript_dlg[19].d1;
18274
18275 if(lind < 0 || rind < 0)
18276 break;
18277
18278 if(asnpcscripts[rind] == "<none>")
18279 {
18280 npcmap[lind].scriptname = "";
18281 npcmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18282 }
18283 else
18284 {
18285 npcmap[lind].updateName(asnpcscripts[rind]);
18286 npcmap[lind].format = scripts[npcmap[lind].scriptname].format;
18287 }
18288
18289 break;
18290 }
18291 case 23:
18292 //<<, LWeapon
18293 {
18294 int32_t lind = assignscript_dlg[21].d1;
18295 int32_t rind = assignscript_dlg[22].d1;
18296
18297 if(lind < 0 || rind < 0)
18298 break;
18299
18300 if(aslweaponscripts[rind] == "<none>")
18301 {
18302 lwpnmap[lind].scriptname = "";
18303 lwpnmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18304 }
18305 else
18306 {
18307 lwpnmap[lind].updateName(aslweaponscripts[rind]);
18308 lwpnmap[lind].format = scripts[lwpnmap[lind].scriptname].format;
18309 }
18310
18311 break;
18312 }
18313 case 26:
18314 //<<, EWeapon
18315 {
18316 int32_t lind = assignscript_dlg[24].d1;
18317 int32_t rind = assignscript_dlg[25].d1;
18318
18319 if(lind < 0 || rind < 0)
18320 break;
18321
18322 if(aseweaponscripts[rind] == "<none>")
18323 {
18324 ewpnmap[lind].scriptname = "";
18325 ewpnmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18326 }
18327 else
18328 {
18329 ewpnmap[lind].updateName(aseweaponscripts[rind]);
18330 ewpnmap[lind].format = scripts[ewpnmap[lind].scriptname].format;
18331 }
18332
18333 break;
18334 }
18335 case 29:
18336 //<<, Hero
18337 {
18338 int32_t lind = assignscript_dlg[27].d1;
18339 int32_t rind = assignscript_dlg[28].d1;
18340
18341 if(lind < 0 || rind < 0)
18342 break;
18343
18344 if(asplayerscripts[rind] == "<none>")
18345 {
18346 playermap[lind].scriptname = "";
18347 playermap[lind].format = SCRIPT_FORMAT_DEFAULT;
18348 }
18349 else
18350 {
18351 playermap[lind].updateName(asplayerscripts[rind]);
18352 playermap[lind].format = scripts[playermap[lind].scriptname].format;
18353 }
18354
18355 break;
18356 }
18357 case 32:
18358 //<<, Screendata
18359 {
18360 int32_t lind = assignscript_dlg[30].d1;
18361 int32_t rind = assignscript_dlg[31].d1;
18362
18363 if(lind < 0 || rind < 0)
18364 break;
18365
18366 if(asscreenscripts[rind] == "<none>")
18367 {
18368 screenmap[lind].scriptname = "";
18369 screenmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18370 }
18371 else
18372 {
18373 screenmap[lind].updateName(asscreenscripts[rind]);
18374 screenmap[lind].format = scripts[screenmap[lind].scriptname].format;
18375 }
18376
18377 break;
18378 }
18379 case 35:
18380 //<<, dmapdata
18381 {
18382 int32_t lind = assignscript_dlg[33].d1;
18383 int32_t rind = assignscript_dlg[34].d1;
18384
18385 if(lind < 0 || rind < 0)
18386 break;
18387
18388 if(asdmapscripts[rind] == "<none>")
18389 {
18390 dmapmap[lind].scriptname = "";
18391 dmapmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18392 }
18393 else
18394 {
18395 dmapmap[lind].updateName(asdmapscripts[rind]);
18396 dmapmap[lind].format = scripts[dmapmap[lind].scriptname].format;
18397 }
18398
18399 break;
18400 }
18401 case 38:
18402 //<<, itemsprite
18403 {
18404 int32_t lind = assignscript_dlg[36].d1;
18405 int32_t rind = assignscript_dlg[37].d1;
18406
18407 if(lind < 0 || rind < 0)
18408 break;
18409
18410 if(asitemspritescripts[rind] == "<none>")
18411 {
18412 itemspritemap[lind].scriptname = "";
18413 itemspritemap[lind].format = SCRIPT_FORMAT_DEFAULT;
18414 }
18415 else
18416 {
18417 itemspritemap[lind].updateName(asitemspritescripts[rind]);
18418 itemspritemap[lind].format = scripts[itemspritemap[lind].scriptname].format;
18419 }
18420
18421 break;
18422 }
18423 case 41:
18424 //<<, comboscript
18425 {
18426 int32_t lind = assignscript_dlg[39].d1;
18427 int32_t rind = assignscript_dlg[40].d1;
18428
18429 if(lind < 0 || rind < 0)
18430 break;
18431
18432 if(ascomboscripts[rind] == "<none>")
18433 {
18434 comboscriptmap[lind].scriptname = "";
18435 comboscriptmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18436 }
18437 else
18438 {
18439 comboscriptmap[lind].updateName(ascomboscripts[rind]);
18440 comboscriptmap[lind].format = scripts[comboscriptmap[lind].scriptname].format;
18441 }
18442
18443 break;
18444 }
18445 case 47:
18446 //<<, generic script
18447 {
18448 int32_t lind = assignscript_dlg[45].d1;
18449 int32_t rind = assignscript_dlg[46].d1;
18450
18451 if(lind < 0 || rind < 0)
18452 break;
18453
18454 if(asgenericscripts[rind] == "<none>")
18455 {
18456 genericmap[lind].scriptname = "";
18457 genericmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18458 }
18459 else
18460 {
18461 genericmap[lind].updateName(asgenericscripts[rind]);
18462 genericmap[lind].format = scripts[genericmap[lind].scriptname].format;
18463 }
18464
18465 break;
18466 }
18467 case 50:
18468 //<<, subscreen script
18469 {
18470 int32_t lind = assignscript_dlg[48].d1;
18471 int32_t rind = assignscript_dlg[49].d1;
18472
18473 if(lind < 0 || rind < 0)
18474 break;
18475
18476 if(assubscreenscripts[rind] == "<none>")
18477 {
18478 subscreenmap[lind].scriptname = "";
18479 subscreenmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18480 }
18481 else
18482 {
18483 subscreenmap[lind].updateName(assubscreenscripts[rind]);
18484 subscreenmap[lind].format = scripts[subscreenmap[lind].scriptname].format;
18485 }
18486
18487 break;
18488 }
18489
18490 case 42:
18491 //Script Info, information
18492 {
18493 disassembled_script_data* target = nullptr;
18494 switch(get_selected_tab((TABPANEL*)assignscript_dlg[1].dp))
18495 {
18496 default:
18497 case 0: //FFC
18498 {
18499 int32_t id = assignscript_dlg[4].d1;
18500 if(id > -1 && ffcmap[id].hasScriptData())
18501 {
18502 target = &(scripts[ffcmap[id].scriptname]);
18503 }
18504 break;
18505 }
18506 case 1: //Global
18507 {
18508 int32_t id = assignscript_dlg[7].d1;
18509 if(id > -1 && globalmap[id].hasScriptData())
18510 {
18511 target = &(scripts[globalmap[id].scriptname]);
18512 }
18513 break;
18514 }
18515 case 2: //Item
18516 {
18517 int32_t id = assignscript_dlg[10].d1;
18518 if(id > -1 && itemmap[id].hasScriptData())
18519 {
18520 target = &(scripts[itemmap[id].scriptname]);
18521 }
18522 break;
18523 }
18524 case 3: //npc
18525 {
18526 int32_t id = assignscript_dlg[19].d1;
18527 if(id > -1 && npcmap[id].hasScriptData())
18528 {
18529 target = &(scripts[npcmap[id].scriptname]);
18530 }
18531 break;
18532 }
18533 case 4: //lweapon
18534 {
18535 int32_t id = assignscript_dlg[21].d1;
18536 if(id > -1 && lwpnmap[id].hasScriptData())
18537 {
18538 target = &(scripts[lwpnmap[id].scriptname]);
18539 }
18540 break;
18541 }
18542 case 5: //eweapon
18543 {
18544 int32_t id = assignscript_dlg[24].d1;
18545 if(id > -1 && ewpnmap[id].hasScriptData())
18546 {
18547 target = &(scripts[ewpnmap[id].scriptname]);
18548 }
18549 break;
18550 }
18551 case 6: //hero
18552 {
18553 int32_t id = assignscript_dlg[27].d1;
18554 if(id > -1 && playermap[id].hasScriptData())
18555 {
18556 target = &(scripts[playermap[id].scriptname]);
18557 }
18558 break;
18559 }
18560 case 7: //dmap
18561 {
18562 int32_t id = assignscript_dlg[33].d1;
18563 if(id > -1 && dmapmap[id].hasScriptData())
18564 {
18565 target = &(scripts[dmapmap[id].scriptname]);
18566 }
18567 break;
18568 }
18569 case 8: //screen
18570 {
18571 int32_t id = assignscript_dlg[30].d1;
18572 if(id > -1 && screenmap[id].hasScriptData())
18573 {
18574 target = &(scripts[screenmap[id].scriptname]);
18575 }
18576 break;
18577 }
18578 case 9: //itemsprite
18579 {
18580 int32_t id = assignscript_dlg[36].d1;
18581 if(id > -1 && itemspritemap[id].hasScriptData())
18582 {
18583 target = &(scripts[itemspritemap[id].scriptname]);
18584 }
18585 break;
18586 }
18587 case 10: //combo
18588 {
18589 int32_t id = assignscript_dlg[39].d1;
18590 if(id > -1 && comboscriptmap[id].hasScriptData())
18591 {
18592 target = &(scripts[comboscriptmap[id].scriptname]);
18593 }
18594 break;
18595 }
18596 case 11: //Generic
18597 {
18598 int32_t id = assignscript_dlg[45].d1;
18599 if(id > -1 && genericmap[id].hasScriptData())
18600 {
18601 target = &(scripts[genericmap[id].scriptname]);
18602 }
18603 break;
18604 }
18605 case 12: //Subscreen
18606 {
18607 int32_t id = assignscript_dlg[48].d1;
18608 if(id > -1 && subscreenmap[id].hasScriptData())
18609 {
18610 target = &(scripts[subscreenmap[id].scriptname]);
18611 }
18612 break;
18613 }
18614 }
18615 if(target)
18616 showScriptInfo(&target->meta);
18617 break;
18618 }
18619
18620 case 43:
18621 //Script Info, information
18622 {
18623 disassembled_script_data* target = NULL;
18624 switch(get_selected_tab((TABPANEL*)assignscript_dlg[1].dp))
18625 {
18626 default:
18627 case 0: //FFC
18628 {
18629 int32_t id = assignscript_dlg[5].d1;
18630 if(id < 0 || asffcscripts[id] == "<none>" || asffcscripts[id].at(0) == '-') break;
18631 target = &(scripts[asffcscripts[id]]);
18632 break;
18633 }
18634 case 1: //Global
18635 {
18636 int32_t id = assignscript_dlg[8].d1;
18637 if(id < 0 || asglobalscripts[id] == "<none>" || asglobalscripts[id].at(0) == '-') break;
18638 target = &(scripts[asglobalscripts[id]]);
18639 break;
18640 }
18641 case 2: //Item
18642 {
18643 int32_t id = assignscript_dlg[11].d1;
18644 if(id < 0 || asitemscripts[id] == "<none>" || asitemscripts[id].at(0) == '-') break;
18645 target = &(scripts[asitemscripts[id]]);
18646 break;
18647 }
18648 case 3: //npc
18649 {
18650 int32_t id = assignscript_dlg[20].d1;
18651 if(id < 0 || asnpcscripts[id] == "<none>" || asnpcscripts[id].at(0) == '-') break;
18652 target = &(scripts[asnpcscripts[id]]);
18653 break;
18654 }
18655 case 4: //lweapon
18656 {
18657 int32_t id = assignscript_dlg[22].d1;
18658 if(id < 0 || aslweaponscripts[id] == "<none>" || aslweaponscripts[id].at(0) == '-') break;
18659 target = &(scripts[aslweaponscripts[id]]);
18660 break;
18661 }
18662 case 5: //eweapon
18663 {
18664 int32_t id = assignscript_dlg[25].d1;
18665 if(id < 0 || aseweaponscripts[id] == "<none>" || aseweaponscripts[id].at(0) == '-') break;
18666 target = &(scripts[aseweaponscripts[id]]);
18667 break;
18668 }
18669 case 6: //hero
18670 {
18671 int32_t id = assignscript_dlg[28].d1;
18672 if(id < 0 || asplayerscripts[id] == "<none>" || asplayerscripts[id].at(0) == '-') break;
18673 target = &(scripts[asplayerscripts[id]]);
18674 break;
18675 }
18676 case 7: //dmap
18677 {
18678 int32_t id = assignscript_dlg[34].d1;
18679 if(id < 0 || asdmapscripts[id] == "<none>" || asdmapscripts[id].at(0) == '-') break;
18680 target = &(scripts[asdmapscripts[id]]);
18681 break;
18682 }
18683 case 8: //screen
18684 {
18685 int32_t id = assignscript_dlg[31].d1;
18686 if(id < 0 || asscreenscripts[id] == "<none>" || asscreenscripts[id].at(0) == '-') break;
18687 target = &(scripts[asscreenscripts[id]]);
18688 break;
18689 }
18690 case 9: //itemsprite
18691 {
18692 int32_t id = assignscript_dlg[37].d1;
18693 if(id < 0 || asitemspritescripts[id] == "<none>" || asitemspritescripts[id].at(0) == '-') break;
18694 target = &(scripts[asitemspritescripts[id]]);
18695 break;
18696 }
18697 case 10: //combo
18698 {
18699 int32_t id = assignscript_dlg[40].d1;
18700 if(id < 0 || ascomboscripts[id] == "<none>" || ascomboscripts[id].at(0) == '-') break;
18701 target = &(scripts[ascomboscripts[id]]);
18702 break;
18703 }
18704 case 11: //generic
18705 {
18706 int32_t id = assignscript_dlg[46].d1;
18707 if(id < 0 || asgenericscripts[id] == "<none>" || asgenericscripts[id].at(0) == '-') break;
18708 target = &(scripts[asgenericscripts[id]]);
18709 break;
18710 }
18711 case 12: //subscreen
18712 {
18713 int32_t id = assignscript_dlg[49].d1;
18714 if(id < 0 || assubscreenscripts[id] == "<none>" || assubscreenscripts[id].at(0) == '-') break;
18715 target = &(scripts[assubscreenscripts[id]]);
18716 break;
18717 }
18718 }
18719 if(target)
18720 showScriptInfo(&target->meta);
18721 break;
18722 }
18723
18724 case 44:
18725 //Clear, clear slots of current type- after a confirmation.
18726 {
18727 doClearSlots(&slotflags);
18728 break;
18729 }
18730 }
18731 }
18732
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(assign_mode == 2) //Smart Assign
18733 {
18734 //For global/hero scripts, match slot names if unoccupied
18735 smart_slot_named(scripts, asglobalscripts, globalmap, global_slotnames, 1, NUMSCRIPTGLOBAL);
18736 smart_slot_named(scripts, asplayerscripts, playermap, player_slotnames, 0, NUMSCRIPTHERO-1);
18737 //For other scripts, assign all un-assigned scripts
18738 smart_slot_type(scripts, asffcscripts, ffcmap, NUMSCRIPTFFC-1);
18739 smart_slot_type(scripts, asitemscripts, itemmap, NUMSCRIPTITEM-1);
18740 smart_slot_type(scripts, asnpcscripts, npcmap, NUMSCRIPTGUYS-1);
18741 smart_slot_type(scripts, aslweaponscripts, lwpnmap, NUMSCRIPTWEAPONS-1);
18742 smart_slot_type(scripts, aseweaponscripts, ewpnmap, NUMSCRIPTWEAPONS-1);
18743 smart_slot_type(scripts, asscreenscripts, screenmap, NUMSCRIPTSCREEN-1);
18744 smart_slot_type(scripts, asdmapscripts, dmapmap, NUMSCRIPTSDMAP-1);
18745 smart_slot_type(scripts, asitemspritescripts, itemspritemap, NUMSCRIPTSITEMSPRITE-1);
18746 smart_slot_type(scripts, ascomboscripts, comboscriptmap, NUMSCRIPTSCOMBODATA-1);
18747 smart_slot_type(scripts, asgenericscripts, genericmap, NUMSCRIPTSGENERIC-1);
18748 smart_slot_type(scripts, assubscreenscripts, subscreenmap, NUMSCRIPTSSUBSCREEN-1);
18749 }
18750 auto_do_slots:
18751 6 doslots_log_output = (assignscript_dlg[13].flags == D_SELECTED);
18752 6 doslots_comment_output = (assignscript_dlg[51].flags == D_SELECTED);
18753 6 doslot_scripts = &scripts;
18754 //OK
18755 {
18756
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(doslots_log_output)
18757 {
18758 string outstr;
18759 write_script(zasm, outstr, doslots_comment_output, doslot_scripts);
18760 safe_al_trace(outstr);
18761 }
18762 6 auto start_assign_time = std::chrono::steady_clock::now();
18763 6 string zasm_str;
18764
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write_script(zasm, zasm_str, false, nullptr);
18765
18766 6 std::vector<ffscript> zasm;
18767
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(parse_script_string(zasm, zasm_str, false))
18768 goto exit_do_slots;
18769
18770 6 zasm_scripts.clear();
18771
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 zasm_scripts.emplace_back(std::make_shared<zasm_script>(std::move(zasm)));
18772
18773
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(ffcmap, 1, ffscripts))
18774 goto exit_do_slots;
18775
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(globalmap, 0, globalscripts))
18776 goto exit_do_slots;
18777
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(itemmap, 1, itemscripts))
18778 goto exit_do_slots;
18779
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(npcmap, 1, guyscripts))
18780 goto exit_do_slots;
18781
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(lwpnmap, 1, lwpnscripts))
18782 goto exit_do_slots;
18783
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(ewpnmap, 1, ewpnscripts))
18784 goto exit_do_slots;
18785
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(playermap, 1, playerscripts))
18786 goto exit_do_slots;
18787
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(dmapmap, 1, dmapscripts))
18788 goto exit_do_slots;
18789
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(screenmap, 1, screenscripts))
18790 goto exit_do_slots;
18791
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(itemspritemap, 1, itemspritescripts))
18792 goto exit_do_slots;
18793
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(comboscriptmap, 1, comboscripts))
18794 goto exit_do_slots;
18795
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(genericmap, 1, genericscripts))
18796 goto exit_do_slots;
18797
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(subscreenmap, 1, subscreenscripts))
18798 goto exit_do_slots;
18799
18800 6 auto end_assign_time = std::chrono::steady_clock::now();
18801
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 int compile_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end_assign_time - start_assign_time).count();
18802
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 al_trace("Assign Slots took %d ms\n", compile_time_ms);
18803 6 char buf[256] = {0};
18804 12 sprintf(buf, "ZScripts successfully loaded into script slots"
18805 6 "\nAssign Slots took %d ms", compile_time_ms);
18806
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 auto sfx_id = vbound(zc_get_config("Compiler","compile_finish_sample",20),0,255);
18807
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 auto sfx_vol = vbound(zc_get_config("Compiler","compile_audio_volume",100),0,255);
18808
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if ( sfx_id > 0 && sfx_vol > 0)
18809
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 sfx(sfx_id, 128, false, true, sfx_vol / 1.28_zf);
18810
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(!assign_mode)
18811 InfoDialog("Slots Assigned",buf).show();
18812
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 kill_sfx();
18813 6 retval = true;
18814 6 goto exit_do_slots;
18815
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 }
18816 exit_do_slots:
18817 6 doslot_scripts = nullptr;
18818 6 popup_zqdialog_end();
18819 6 return retval;
18820 }
18821
18822 static char slottype_str_buf[32];
18823
18824 const char *slottype_list(int32_t index, int32_t *list_size)
18825 {
18826 if(index >= 0)
18827 {
18828 bound(index,0,num_types-1);
18829
18830 switch(index)
18831 {
18832 case type_ffc:
18833 strcpy(slottype_str_buf, "FFC");
18834 break;
18835 case type_global:
18836 strcpy(slottype_str_buf, "Global");
18837 break;
18838 case type_itemdata:
18839 strcpy(slottype_str_buf, "Item");
18840 break;
18841 case type_npc:
18842 strcpy(slottype_str_buf, "NPC");
18843 break;
18844 case type_lweapon:
18845 strcpy(slottype_str_buf, "LWeapon");
18846 break;
18847 case type_eweapon:
18848 strcpy(slottype_str_buf, "EWeapon");
18849 break;
18850 case type_hero:
18851 strcpy(slottype_str_buf, "Hero");
18852 break;
18853 case type_dmap:
18854 strcpy(slottype_str_buf, "DMap");
18855 break;
18856 case type_screen:
18857 strcpy(slottype_str_buf, "Screen");
18858 break;
18859 case type_itemsprite:
18860 strcpy(slottype_str_buf, "ItemSprite");
18861 break;
18862 case type_combo:
18863 strcpy(slottype_str_buf, "Combo");
18864 break;
18865 case type_generic:
18866 strcpy(slottype_str_buf, "Generic");
18867 break;
18868 case type_subscreen:
18869 strcpy(slottype_str_buf, "Subscreen");
18870 break;
18871 }
18872
18873 return slottype_str_buf;
18874 }
18875 *list_size = 11;
18876 return NULL;
18877 }
18878 12 static ListData slottype_sel_list(slottype_list, &font);
18879
18880 static DIALOG clearslots_dlg[] =
18881 {
18882 12 { jwin_win_proc, 0, 0, 200, 159, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Clear Slots", NULL, NULL },
18883 12 { jwin_button_proc, 35, 132, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Confirm", NULL, NULL },
18884 12 { jwin_button_proc, 104, 132, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
18885 12 { jwin_droplist_proc, 50, 28+16, 70, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &slottype_sel_list, NULL, NULL },
18886 12 { jwin_radio_proc, 40, 34+00, 81, 9, vc(14), vc(1), 0, D_SELECTED, 0, 0, (void *) "Clear Script Type:", NULL, NULL },
18887 12 { jwin_radio_proc, 40, 34+32, 81, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "Clear Missing (--) Slots", NULL, NULL },
18888 12 { jwin_radio_proc, 40, 34+80, 81, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "Clear All", NULL, NULL },
18889 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
18890 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
18891 };
18892
18893 void doClearSlots(byte* flags)
18894 {
18895 //{ Setup
18896 clearslots_dlg[0].dp2=get_zc_font(font_lfont);
18897 clearslots_dlg[3].d1 = get_selected_tab((TABPANEL*)assignscript_dlg[1].dp); //Default to current tab's type
18898 clearslots_dlg[4].flags |= D_SELECTED;
18899 clearslots_dlg[5].flags &= ~D_SELECTED;
18900 clearslots_dlg[6].flags &= ~D_SELECTED;
18901 if(((*flags) & SLOTMSGFLAG_MISSING) == 0)
18902 clearslots_dlg[5].flags |= D_DISABLED;
18903 else
18904 clearslots_dlg[5].flags &= ~D_DISABLED;
18905 //}
18906
18907 large_dialog(clearslots_dlg);
18908
18909 if(do_zqdialog(clearslots_dlg,2)==1)
18910 {
18911 int32_t q = 3;
18912 while((clearslots_dlg[++q].flags & D_SELECTED) == 0);
18913 switch(q)
18914 {
18915 case 4: //Clear type
18916 {
18917 clearAllSlots(clearslots_dlg[3].d1);
18918 break;
18919 }
18920 case 5: //Clear Missing
18921 {
18922 for(int32_t q = 0; q <= 10; ++q)
18923 clearAllSlots(q,SLOTMSGFLAG_MISSING);
18924 break;
18925 }
18926 case 6: //Clear ALL
18927 {
18928 for(int32_t q = 0; q <= 10; ++q)
18929 clearAllSlots(q);
18930 break;
18931 }
18932 }
18933 }
18934 }
18935
18936 static DIALOG exportzasm_dlg[] =
18937 {
18938 12 { jwin_win_proc, 0, 0, 200, 159, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Export ZASM", NULL, NULL },
18939 12 { jwin_button_proc, 35, 132, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Confirm", NULL, NULL },
18940 12 { jwin_button_proc, 104, 132, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
18941 12 { jwin_droplist_proc, 50, 28+16, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, (void *) &slottype_sel_list, NULL, NULL },
18942 12 { jwin_droplist_proc, 50, 28+48, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
18943 12 { jwin_text_proc, 50, 28+8, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Type:", NULL, NULL },
18944 12 { jwin_text_proc, 50, 28+40, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Slot:", NULL, NULL },
18945 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
18946 };
18947
18948 static DIALOG importzasm_dlg[] =
18949 {
18950 12 { jwin_win_proc, 0, 0, 200, 159, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Import ZASM", NULL, NULL },
18951 12 { jwin_button_proc, 35, 132, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Confirm", NULL, NULL },
18952 12 { jwin_button_proc, 104, 132, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
18953 12 { jwin_droplist_proc, 50, 28+16, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, (void *) &slottype_sel_list, NULL, NULL },
18954 12 { jwin_droplist_proc, 50, 28+48, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
18955 // 5
18956 12 { jwin_text_proc, 50, 28+8, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Type:", NULL, NULL },
18957 12 { jwin_text_proc, 50, 28+40, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Slot:", NULL, NULL },
18958 12 { jwin_text_proc, 50, 28+72, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Name:", NULL, NULL },
18959 12 { jwin_edit_proc, 50, 28+80, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 19, 0, NULL, NULL, NULL },
18960
18961 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
18962 };
18963
18964 1 void center_zscript_dialogs()
18965 {
18966 1 jwin_center_dialog(exportzasm_dlg);
18967 1 jwin_center_dialog(importzasm_dlg);
18968 1 jwin_center_dialog(clearslots_dlg);
18969 1 }
18970
18971 // array of voices, one for each sfx sample in the data file
18972 // 0+ = voice #
18973 // -1 = voice not allocated
18974 int32_t sfx_voice[WAV_COUNT];
18975
18976 void Z_init_sound()
18977 {
18978 for(int32_t i=0; i<WAV_COUNT; i++)
18979 sfx_voice[i]=-1;
18980
18981 // master_volume(digi_volume,midi_volume);
18982 }
18983
18984 // returns number of voices currently allocated
18985 int32_t sfx_count()
18986 {
18987 int32_t c=0;
18988
18989 for(int32_t i=0; i<WAV_COUNT; i++)
18990 if(sfx_voice[i]!=-1)
18991 ++c;
18992
18993 return c;
18994 }
18995
18996 // clean up finished samples
18997 void sfx_cleanup()
18998 {
18999 for(int32_t i=0; i<WAV_COUNT; i++)
19000 if(sfx_voice[i]!=-1 && voice_get_position(sfx_voice[i])<0)
19001 {
19002 deallocate_voice(sfx_voice[i]);
19003 sfx_voice[i]=-1;
19004 }
19005 }
19006
19007 bool sfx_templist = false;
19008 SAMPLE templist[WAV_COUNT];
19009 12 SAMPLE* sfx_get_sample(int32_t index)
19010 {
19011 // check index
19012
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if (index<=0 || index>=WAV_COUNT)
19013 return nullptr;
19014
19015
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (sfx_templist)
19016 {
19017 if (templist[index].data)
19018 return &templist[index];
19019 else return nullptr;
19020 }
19021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 else if (sfxdat)
19022 {
19023 if (index<Z35)
19024 {
19025 return (SAMPLE*)sfxdata[index].dat;
19026 }
19027 else
19028 {
19029 return (SAMPLE*)sfxdata[Z35].dat;
19030 }
19031 }
19032 else
19033 {
19034 12 return &customsfxdata[index];
19035 }
19036
19037 return nullptr;
19038 12 }
19039
19040 12 bool sfx_init(int32_t index)
19041 {
19042 // check index
19043
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(index<1 || index>=WAV_COUNT)
19044 return false;
19045
19046
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(sfx_voice[index]==-1)
19047 {
19048 12 SAMPLE* sample = sfx_get_sample(index);
19049
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (!sample)
19050 return false;
19051
19052 12 sfx_voice[index] = allocate_voice(sample);
19053 12 }
19054
19055 12 return sfx_voice[index] != -1;
19056 12 }
19057
19058 // plays an sfx sample
19059 12 void sfx(int32_t index,int32_t pan,bool loop,bool restart,zfix vol_perc,int32_t freq)
19060 {
19061
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(!sfx_init(index))
19062 return;
19063
19064 12 voice_set_playmode(sfx_voice[index],loop?PLAYMODE_LOOP:PLAYMODE_PLAY);
19065 12 voice_set_pan(sfx_voice[index],pan);
19066
19067 12 int32_t pos = voice_get_position(sfx_voice[index]);
19068
19069 12 int temp_volume = (128 * (vol_perc / 100)).getFloor();
19070
19071
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(restart) voice_set_position(sfx_voice[index],0);
19072 12 voice_set_volume(sfx_voice[index], temp_volume);
19073
19074
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(pos<=0)
19075 12 voice_start(sfx_voice[index]);
19076 12 }
19077
19078 // start it (in loop mode) if it's not already playing,
19079 // otherwise just leave it in its current position
19080 void cont_sfx(int32_t index)
19081 {
19082 if(!sfx_init(index))
19083 return;
19084
19085 if(voice_get_position(sfx_voice[index])<=0)
19086 {
19087 voice_set_position(sfx_voice[index],0);
19088 voice_set_playmode(sfx_voice[index],PLAYMODE_LOOP);
19089 voice_start(sfx_voice[index]);
19090 }
19091 }
19092
19093 // adjust parameters while playing
19094 void adjust_sfx(int32_t index,int32_t pan,bool loop)
19095 {
19096 if(index<0 || index>=WAV_COUNT || sfx_voice[index]==-1)
19097 return;
19098
19099 voice_set_playmode(sfx_voice[index],loop?PLAYMODE_LOOP:PLAYMODE_PLAY);
19100 voice_set_pan(sfx_voice[index],pan);
19101 }
19102
19103 // pauses a voice
19104 void pause_sfx(int32_t index)
19105 {
19106 if(index>=0 && index<WAV_COUNT && sfx_voice[index]!=-1)
19107 voice_stop(sfx_voice[index]);
19108 }
19109
19110 // resumes a voice
19111 void resume_sfx(int32_t index)
19112 {
19113 if(index>=0 && index<WAV_COUNT && sfx_voice[index]!=-1)
19114 voice_start(sfx_voice[index]);
19115 }
19116
19117 // pauses all active voices
19118 void pause_all_sfx()
19119 {
19120 for(int32_t i=0; i<WAV_COUNT; i++)
19121 if(sfx_voice[i]!=-1)
19122 voice_stop(sfx_voice[i]);
19123 }
19124
19125 // resumes all paused voices
19126 void resume_all_sfx()
19127 {
19128 for(int32_t i=0; i<WAV_COUNT; i++)
19129 if(sfx_voice[i]!=-1)
19130 voice_start(sfx_voice[i]);
19131 }
19132
19133 // stops an sfx and deallocates the voice
19134 void stop_sfx(int32_t index)
19135 {
19136 if(index<0 || index>=WAV_COUNT)
19137 return;
19138
19139 if(sfx_voice[index]!=-1)
19140 {
19141 deallocate_voice(sfx_voice[index]);
19142 sfx_voice[index]=-1;
19143 }
19144 }
19145
19146 18 void kill_sfx()
19147 {
19148
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 18 times.
4626 for(int32_t i=0; i<WAV_COUNT; i++)
19149
2/2
✓ Branch 0 taken 3060 times.
✓ Branch 1 taken 1548 times.
6156 if(sfx_voice[i]!=-1)
19150 {
19151 1548 deallocate_voice(sfx_voice[i]);
19152 1548 sfx_voice[i]=-1;
19153 1548 }
19154 18 }
19155
19156 int32_t pan(int32_t x)
19157 {
19158 return 128;
19159 /*switch(pan_style)
19160 {
19161 case 0: return 128;
19162 case 1: return vbound((x>>1)+68,0,255);
19163 case 2: return vbound(((x*3)>>2)+36,0,255);
19164 }
19165 return vbound(x,0,255);*/
19166 }
19167
19168
19169 void change_sfx(SAMPLE *sfx1, SAMPLE *sfx2)
19170 {
19171 sfx1->bits = sfx2->bits;
19172 sfx1->stereo = sfx2->stereo;
19173 sfx1->freq = sfx2->freq;
19174 sfx1->priority = sfx2->priority;
19175 sfx1->len = sfx2->len;
19176 sfx1->loop_start = sfx2->loop_start;
19177 sfx1->loop_end = sfx2->loop_end;
19178 sfx1->param = sfx2->param;
19179
19180 if(sfx1->data != NULL)
19181 {
19182 free(sfx1->data);
19183 }
19184
19185 if(sfx2->data == NULL)
19186 sfx1->data = NULL;
19187 else
19188 {
19189 // When quests are saved and loaded, data is written in words.
19190 // If the last byte is dropped, it'll cause the sound to end with
19191 // a click. It could simply be extended and padded with 0, but
19192 // that causes compatibility issues... So we'll cut off
19193 // the last byte and decrease the length.
19194
19195 int32_t len = (sfx1->bits==8?1:2)*(sfx1->stereo == 0 ? 1 : 2)*sfx1->len;
19196
19197 while(len%sizeof(word))
19198 {
19199 // sizeof(word) should be 2, so this doesn't really need
19200 // to be a loop, but what the heck.
19201 sfx1->len--;
19202 len = (sfx1->bits==8?1:2)*(sfx1->stereo == 0 ? 1 : 2)*sfx1->len;
19203 }
19204
19205 sfx1->data = malloc(len);
19206 memcpy(sfx1->data, sfx2->data, len);
19207 }
19208 }
19209
19210 int32_t onSelectSFX()
19211 {
19212 SFXListerDialog(0).show();
19213 refresh(rMAP+rCOMBOS);
19214 return D_O_K;
19215 }
19216
19217 bool saveWAV(int32_t slot, const char *filename)
19218 {
19219 if (slot < 1 || slot >= 511 )
19220 return false;
19221
19222 if (customsfxdata[slot].data == NULL)
19223 return false;
19224
19225 std::ofstream ofs(filename, std::ios::binary);
19226 if (!ofs)
19227 return false;
19228 ofs.write("RIFF",4);
19229 uint32_t samplerate = customsfxdata[slot].freq;
19230 uint16_t channels = customsfxdata[slot].stereo ? 2 : 1;
19231 uint32_t datalen = customsfxdata[slot].len*channels*customsfxdata[slot].bits / 8;
19232 uint32_t size = 36 + datalen;
19233 ofs.write((char *)&size, 4);
19234 ofs.write("WAVE", 4);
19235 ofs.write("fmt ", 4);
19236 uint32_t fmtlen = 16;
19237 ofs.write((char *)&fmtlen, 4);
19238 uint16_t type = 1;
19239 ofs.write((char *)&type, 2);
19240 ofs.write((char *)&channels, 2);
19241 ofs.write((char *)&samplerate, 4);
19242 uint32_t bytespersec = samplerate*channels*customsfxdata[slot].bits / 8;
19243 ofs.write((char *)&bytespersec, 4);
19244 uint16_t blockalign = channels*customsfxdata[slot].bits / 8;
19245 ofs.write((char *)&blockalign, 2);
19246 uint16_t bitspersample = customsfxdata[slot].bits;
19247 ofs.write((char *)&bitspersample, 2);
19248 ofs.write("data", 4);
19249 ofs.write((char *)&datalen, 4);
19250 if (bitspersample == 8)
19251 {
19252 for (int32_t i = 0; i < (int32_t)customsfxdata[slot].len*channels; i++)
19253 {
19254 char data = ((char *)customsfxdata[slot].data)[i];
19255 data ^= 0x80;
19256 ofs.write(&data, 1);
19257 }
19258 }
19259 else if (bitspersample == 16)
19260 {
19261 for (int32_t i = 0; i < (int32_t)customsfxdata[slot].len*channels; i++)
19262 {
19263 uint16_t data = ((uint16_t *)customsfxdata[slot].data)[i];
19264 data ^= 0x8000;
19265 ofs.write((char *)&data, 2);
19266 }
19267 }
19268 else
19269 return false;
19270 return !!ofs;
19271 }
19272
19273 int32_t onMapStyles()
19274 {
19275 call_mapstyles_dialog();
19276 return D_O_K;
19277 }
19278
19279 int32_t d_misccolors_old_proc(int32_t msg,DIALOG *d,int32_t c)
19280 {
19281 //these are here to bypass compiler warnings about unused arguments
19282 c=c;
19283
19284 if(msg==MSG_DRAW)
19285 {
19286 textout_ex(screen,font,"0123456789ABCDEF",d->x+8,d->y,d->fg,d->bg);
19287 textout_ex(screen,font,"0",d->x,d->y+8,d->fg,d->bg);
19288 textout_ex(screen,font,"1",d->x,d->y+16,d->fg,d->bg);
19289 textout_ex(screen,font,"5",d->x,d->y+24,d->fg,d->bg);
19290
19291 for(int32_t i=0; i<32; i++)
19292 {
19293 int32_t px2 = d->x+((i&15)<<3)+8;
19294 int32_t py2 = d->y+((i>>4)<<3)+8;
19295 rectfill(screen,px2,py2,px2+7,py2+7,i);
19296 }
19297
19298 for(int32_t i=0; i<16; i++)
19299 {
19300 int32_t px2 = d->x+(i<<3)+8;
19301 rectfill(screen,px2,d->y+24,px2+7,d->y+31,i+80);
19302 }
19303 }
19304
19305 return D_O_K;
19306 }
19307
19308 int32_t hexclicked=-1;
19309
19310 int32_t d_misccolors_hexedit_proc(int32_t msg,DIALOG *d,int32_t c)
19311 {
19312 switch(msg)
19313 {
19314 case MSG_GOTFOCUS:
19315 hexclicked=((int32_t)(size_t)(d->dp3))+20;
19316 break;
19317
19318 case MSG_LOSTFOCUS:
19319 hexclicked=-1;
19320 break;
19321 }
19322
19323 return d_hexedit_proc(msg,d,c);
19324 }
19325
19326
19327 int32_t d_misccolors_proc(int32_t msg,DIALOG *d,int32_t c);
19328
19329 static int32_t misccolor1_list[] =
19330 {
19331 // dialog control number
19332 4, 5, 6, 7, 8, 20, 21, 22, 23, 24, 36, 37, 38, 39, 40, -1
19333 };
19334
19335 static int32_t misccolor2_list[] =
19336 {
19337 // dialog control number
19338 9, 10, 11, 12, 13, 25, 26, 27, 28, 29, 41, 42, 43, 44, 45, -1
19339 };
19340
19341 static int32_t misccolor3_list[] =
19342 {
19343 // dialog control number
19344 14, 15, 16, 17, 18, 30, 31, 32, 33, 34, 46, 47, 48, 49, 50, -1
19345 };
19346
19347 static int32_t misccolor4_list[] =
19348 {
19349 19, 35, 51, 54, 55, 56, -1
19350 };
19351
19352 static TABPANEL misccolor_tabs[] =
19353 {
19354 // (text)
19355 { (char *)"1", D_SELECTED, misccolor1_list, 0, NULL },
19356 { (char *)"2", 0, misccolor2_list, 0, NULL },
19357 { (char *)"3", 0, misccolor3_list, 0, NULL },
19358 { (char *)"4", 0, misccolor4_list, 0, NULL },
19359 { NULL, 0, NULL, 0, NULL }
19360 };
19361
19362 int32_t d_misccolors_tab_proc(int32_t msg,DIALOG *d,int32_t c);
19363
19364 static DIALOG misccolors_dlg[] =
19365 {
19366 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
19367 12 { jwin_win_proc, 2, 21, 316, 197-23, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Misc Colors", NULL, NULL },
19368 // { jwin_frame_proc, 98-84+1+2, 52+8-6+4, 132, 100, vc(15), vc(1), 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
19369 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
19370 12 { d_misccolors_proc, 92-84+1+2, 44+8-6+4, 128+8, 96+8, vc(9), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
19371 //3
19372 12 { d_misccolors_tab_proc, 150+14-2+10-15, 60-14, 150-10+15, 144-20-10, jwin_pal[jcBOXFG], jwin_pal[jcBOX], 0, 0, 0, 0, (void *) misccolor_tabs, NULL, (void *)misccolors_dlg },
19373 //4
19374 12 { jwin_text_proc, 215-25-12-15, 76-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Text:", NULL, NULL },
19375 12 { jwin_text_proc, 215-25-12-15, 94-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Caption:", NULL, NULL },
19376 12 { jwin_text_proc, 215-25-12-15, 112-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Overworld Minmap:", NULL, NULL },
19377 12 { jwin_text_proc, 215-25-12-15, 130-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Minimap Background:", NULL, NULL },
19378 12 { jwin_text_proc, 215-25-12-15, 148-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Minimap Foreground 1:", NULL, NULL },
19379 12 { jwin_text_proc, 215-25-12-15, 76-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Minimap Foreground 2:", NULL, NULL },
19380 12 { jwin_text_proc, 215-25-12-15, 94-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "BS Minimap Dark:", NULL, NULL },
19381 12 { jwin_text_proc, 215-25-12-15, 112-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "BS Minimap Goal:", NULL, NULL },
19382 12 { jwin_text_proc, 215-25-12-15, 130-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Compass Mark (Light):", NULL, NULL },
19383 12 { jwin_text_proc, 215-25-12-15, 148-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Compass Mark (Dark):", NULL, NULL },
19384 12 { jwin_text_proc, 215-25-12-15, 76-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Subscreen Background:", NULL, NULL },
19385 12 { jwin_text_proc, 215-25-12-15, 94-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Subscreen Shadow:", NULL, NULL },
19386 12 { jwin_text_proc, 215-25-12-15, 112-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Triforce Frame:", NULL, NULL },
19387 12 { jwin_text_proc, 215-25-12-15, 130-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Big Map Background:", NULL, NULL },
19388 12 { jwin_text_proc, 215-25-12-15, 148-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Big Map Foreground:", NULL, NULL },
19389 12 { jwin_text_proc, 215-25-12-15, 76-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Hero's Position:", NULL, NULL },
19390
19391 //20
19392 12 { d_misccolors_hexedit_proc, 294-25+14+2, 76-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)0, },
19393 12 { d_misccolors_hexedit_proc, 294-25+14+2, 94-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)1, },
19394 12 { d_misccolors_hexedit_proc, 294-25+14+2, 112-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)2, },
19395 12 { d_misccolors_hexedit_proc, 294-25+14+2, 130-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)3, },
19396 12 { d_misccolors_hexedit_proc, 294-25+14+2, 148-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)4, },
19397 12 { d_misccolors_hexedit_proc, 294-25+14+2, 76-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)5, },
19398 12 { d_misccolors_hexedit_proc, 294-25+14+2, 94-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)6, },
19399 12 { d_misccolors_hexedit_proc, 294-25+14+2, 112-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)7, },
19400 12 { d_misccolors_hexedit_proc, 294-25+14+2, 130-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)8, },
19401 12 { d_misccolors_hexedit_proc, 294-25+14+2, 148-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)9, },
19402 12 { d_misccolors_hexedit_proc, 294-25+14+2, 76-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)10, },
19403 12 { d_misccolors_hexedit_proc, 294-25+14+2, 94-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)11, },
19404 12 { d_misccolors_hexedit_proc, 294-25+14+2, 112-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)12, },
19405 12 { d_misccolors_hexedit_proc, 294-25+14+2, 130-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)13, },
19406 12 { d_misccolors_hexedit_proc, 294-25+14+2, 148-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)14, },
19407 12 { d_misccolors_hexedit_proc, 294-25+14+2, 76-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)15, },
19408
19409 //36
19410 12 { jwin_text_proc, 283-25+14+2, 76-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19411 12 { jwin_text_proc, 283-25+14+2, 94-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19412 12 { jwin_text_proc, 283-25+14+2, 112-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19413 12 { jwin_text_proc, 283-25+14+2, 130-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19414 12 { jwin_text_proc, 283-25+14+2, 148-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19415 12 { jwin_text_proc, 283-25+14+2, 76-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19416 12 { jwin_text_proc, 283-25+14+2, 94-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19417 12 { jwin_text_proc, 283-25+14+2, 112-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19418 12 { jwin_text_proc, 283-25+14+2, 130-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19419 12 { jwin_text_proc, 283-25+14+2, 148-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19420 12 { jwin_text_proc, 283-25+14+2, 76-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19421 12 { jwin_text_proc, 283-25+14+2, 94-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19422 12 { jwin_text_proc, 283-25+14+2, 112-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19423 12 { jwin_text_proc, 283-25+14+2, 130-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19424 12 { jwin_text_proc, 283-25+14+2, 148-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19425 12 { jwin_text_proc, 283-25+14+2, 76-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19426
19427 //52
19428 12 { jwin_button_proc, 90, 190-20, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
19429 12 { jwin_button_proc, 170, 190-20, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
19430 12 { jwin_text_proc, 215-25-12-15, 94-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Message Text:", NULL, NULL },
19431 12 { d_misccolors_hexedit_proc, 294-25+14+2, 94-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)35, },
19432 12 { jwin_text_proc, 283-25+14+2, 94-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19433 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
19434 };
19435
19436 int32_t d_misccolors_tab_proc(int32_t msg,DIALOG *d,int32_t c)
19437 {
19438
19439 switch(msg)
19440 {
19441 case MSG_WANTFOCUS:
19442 return D_WANTFOCUS;
19443 break;
19444 }
19445
19446 return jwin_tab_proc(msg,d,c);
19447 }
19448
19449
19450 int32_t d_misccolors_proc(int32_t msg,DIALOG *d,int32_t c)
19451 {
19452 //these are here to bypass compiler warnings about unused arguments
19453 c=c;
19454 int32_t mul=12;
19455
19456 switch(msg)
19457 {
19458 case MSG_CLICK:
19459 if(hexclicked!=-1)
19460 {
19461 int32_t color_col=vbound(((gui_mouse_x()-d->x-8)/mul),0,15);
19462 int32_t color_row=vbound(((gui_mouse_y()-d->y-10)/mul),0,11);
19463 sprintf((char*)misccolors_dlg[hexclicked].dp,"%X%X",color_row,color_col);
19464 object_message(misccolors_dlg+hexclicked,MSG_DRAW,0);
19465 }
19466
19467 break;
19468
19469 case MSG_DRAW:
19470 for(int32_t i=0; i<10; i++)
19471 {
19472 textprintf_centre_ex(screen,font,d->x+8+4+(i*mul),d->y,jwin_pal[jcBOXFG],jwin_pal[jcBOX], "%d", i);
19473 }
19474
19475 for(int32_t i=0; i<6; i++)
19476 {
19477 textprintf_centre_ex(screen,font,d->x+8+4+((10+i)*mul),d->y,jwin_pal[jcBOXFG],jwin_pal[jcBOX], "%c", i+'A');
19478 }
19479
19480 for(int32_t i=0; i<10; i++)
19481 {
19482 textprintf_right_ex(screen,font,d->x+6,d->y+(i*mul)+10,jwin_pal[jcBOXFG],jwin_pal[jcBOX], "%d", i);
19483 }
19484
19485 for(int32_t i=0; i<2; i++)
19486 {
19487 textprintf_right_ex(screen,font,d->x+6,d->y+((i+10)*mul)+10,jwin_pal[jcBOXFG],jwin_pal[jcBOX], "%c", i+'A');
19488 }
19489
19490 jwin_draw_frame(screen,d->x+6,d->y+8,int32_t(132*1.5)-2,int32_t(100*1.5)-2,FR_DEEP);
19491
19492 for(int32_t i=0; i<192; i++)
19493 {
19494 int32_t px2 = d->x+int32_t(((i&15)<<3)*1.5)+8;
19495 int32_t py2 = d->y+int32_t(((i>>4)<<3)*1.5)+8+2;
19496 rectfill(screen,px2,py2,px2+(mul-1),py2+(mul-1),i);
19497 }
19498
19499 break;
19500 }
19501
19502 return D_O_K;
19503 }
19504
19505
19506 int32_t onMiscColors()
19507 {
19508 char buf[17][3];
19509 byte *si = &(QMisc.colors.text);
19510 misccolors_dlg[0].dp2=get_zc_font(font_lfont);
19511
19512 for(int32_t i=0; i<16; i++)
19513 {
19514 sprintf(buf[i],"%02X",*(si++));
19515 sprintf(buf[16], "%02X", QMisc.colors.msgtext);
19516 misccolors_dlg[i+20].dp = buf[i];
19517 misccolors_dlg[55].dp = buf[16];
19518 }
19519
19520 large_dialog(misccolors_dlg);
19521
19522 if(do_zqdialog(misccolors_dlg,0)==52)
19523 {
19524 mark_save_dirty();
19525 si = &(QMisc.colors.text);
19526
19527 for(int32_t i=0; i<16; i++)
19528 {
19529 *si = zc_xtoi(buf[i]);
19530 ++si;
19531 }
19532
19533 QMisc.colors.msgtext = zc_xtoi(buf[16]);
19534 }
19535
19536 return D_O_K;
19537 }
19538
19539 // **** Palette cycling ****
19540
19541 static int32_t palclk[3];
19542 static int32_t palpos[3];
19543
19544 22 void reset_pal_cycling()
19545 {
19546
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 22 times.
88 for(int32_t i=0; i<3; i++)
19547 66 palclk[i]=palpos[i]=0;
19548 22 }
19549
19550 void cycle_palette()
19551 {
19552 if(!get_qr(qr_FADE))
19553 return;
19554
19555 int32_t level = Map.CurrScr()->color;
19556 bool refreshpal = false;
19557
19558 for(int32_t i=0; i<3; i++)
19559 {
19560 palcycle c = QMisc.cycles[level][i];
19561
19562 if(c.count&0xF0)
19563 {
19564 if(++palclk[i] >= c.speed)
19565 {
19566 palclk[i]=0;
19567
19568 if(++palpos[i] >= (c.count>>4))
19569 palpos[i]=0;
19570
19571 byte *si = colordata + CSET(level*pdLEVEL+poFADE1+1+palpos[i])*3;
19572
19573 si += (c.first&15)*3;
19574
19575 for(int32_t col=c.first&15; col<=(c.count&15); col++)
19576 {
19577 RAMpal[CSET(c.first>>4)+col] = _RGB(si);
19578 si+=3;
19579 }
19580
19581 refreshpal = true;
19582 }
19583 }
19584 }
19585
19586 if(refreshpal)
19587 {
19588 rebuild_trans_table();
19589 zc_set_palette_range(RAMpal,0,192,false);
19590 }
19591 }
19592
19593
19594 static void doHelp()
19595 {
19596 do_box_edit(helpstr, "ZQuest Help", true, true);
19597 }
19598
19599 int32_t onHelp()
19600 {
19601 restore_mouse();
19602 doHelp();
19603 return D_O_K;
19604 }
19605
19606 void doZstringshelp()
19607 {
19608 do_box_edit(zstringshelpstr, "ZStrings Help", true, true);
19609 }
19610
19611 int32_t onZstringshelp()
19612 {
19613 restore_mouse();
19614 doZstringshelp();
19615 return D_O_K;
19616 }
19617
19618 void call_layer_dialog(int map, int scr);
19619 int32_t onLayers()
19620 {
19621 call_layer_dialog(Map.getCurrMap(), Map.getCurrScr());
19622 if (CurrentLayer > 0 && Map.CurrScr()->layermap[CurrentLayer-1] == 0)
19623 CurrentLayer = 0;
19624 return D_O_K;
19625 }
19626
19627 void fps_callback()
19628 {
19629 lastfps=framecnt;
19630 framecnt=0;
19631 }
19632
19633 END_OF_FUNCTION(fps_callback)
19634
19635 //uint32_t col_diff[3*128];
19636 /*
19637 void bestfit_init(void)
19638 {
19639 int32_t i;
19640
19641 for (i=1; i<64; i++)
19642
19643 {
19644 int32_t k = i * i;
19645 col_diff[0 +i] = col_diff[0 +128-i] = k * (59 * 59);
19646 col_diff[128+i] = col_diff[128+128-i] = k * (30 * 30);
19647 col_diff[256+i] = col_diff[256+128-i] = k * (11 * 11);
19648 }
19649 }
19650 */
19651 void create_rgb_table2(RGB_MAP *table, AL_CONST PALETTE pal_8bit, void (*callback)(int32_t pos))
19652 {
19653 #define UNUSED 65535
19654 #define LAST 65532
19655
19656 // Allegro has been modified to use an 8 bit palette, but this method and RGB_MAP still use 6 bit.
19657 PALETTE pal;
19658 for (int i = 0; i < 256; i++)
19659 {
19660 pal[i] = pal_8bit[i];
19661 pal[i].r /= 4;
19662 pal[i].g /= 4;
19663 pal[i].b /= 4;
19664 }
19665
19666 /* macro add adds to single linked list */
19667 #define add(i) (next[(i)] == UNUSED ? (next[(i)] = LAST, \
19668 (first != LAST ? (next[last] = (i)) : (first = (i))), \
19669 (last = (i))) : 0)
19670
19671 /* same but w/o checking for first element */
19672 #define add1(i) (next[(i)] == UNUSED ? (next[(i)] = LAST, \
19673 next[last] = (i), \
19674 (last = (i))) : 0)
19675 /* calculates distance between two colors */
19676 #define dist(a1, a2, a3, b1, b2, b3) \
19677 (col_diff[ ((a2) - (b2)) & 0x7F] + \
19678 (col_diff + 128)[((a1) - (b1)) & 0x7F] + \
19679 (col_diff + 256)[((a3) - (b3)) & 0x7F])
19680
19681 /* converts r,g,b to position in array and back */
19682 #define pos(r, g, b) \
19683 (((r) / 2) * 32 * 32 + ((g) / 2) * 32 + ((b) / 2))
19684
19685 #define depos(pal, r, g, b) \
19686 ((b) = ((pal) & 31) * 2, \
19687 (g) = (((pal) >> 5) & 31) * 2, \
19688 (r) = (((pal) >> 10) & 31) * 2)
19689
19690 /* is current color better than pal1? */
19691 #define better(r1, g1, b1, pal1) \
19692 (((int32_t)dist((r1), (g1), (b1), \
19693 (pal1).r, (pal1).g, (pal1).b)) > (int32_t)dist2)
19694
19695 /* checking of position */
19696 #define dopos(rp, gp, bp, ts) \
19697 if ((rp > -1 || r > 0) && (rp < 1 || r < 61) && \
19698 (gp > -1 || g > 0) && (gp < 1 || g < 61) && \
19699 (bp > -1 || b > 0) && (bp < 1 || b < 61)) \
19700 { \
19701 i = first + rp * 32 * 32 + gp * 32 + bp; \
19702 if (!data[i]) \
19703 { \
19704 data[i] = val; \
19705 add1(i); \
19706 } \
19707 else if ((ts) && (data[i] != val)) \
19708 { \
19709 dist2 = (rp ? (col_diff+128)[(r+2*rp-pal[val].r) & 0x7F] : r2) + \
19710 (gp ? (col_diff )[(g+2*gp-pal[val].g) & 0x7F] : g2) + \
19711 (bp ? (col_diff+256)[(b+2*bp-pal[val].b) & 0x7F] : b2); \
19712 if (better((r+2*rp), (g+2*gp), (b+2*bp), pal[data[i]])) \
19713 { \
19714 data[i] = val; \
19715 add1(i); \
19716 } \
19717 } \
19718 }
19719
19720 int32_t i, curr, r, g, b, val, dist2;
19721 uint32_t r2, g2, b2;
19722 uint16_t next[32*32*32];
19723 uint8_t *data;
19724 int32_t first = LAST;
19725 int32_t last = LAST;
19726 int32_t count = 0;
19727 int32_t cbcount = 0;
19728
19729 #define AVERAGE_COUNT 18000
19730
19731 if(col_diff[1] == 0)
19732 bestfit_init();
19733
19734 memset(next, 255, sizeof(next));
19735 memset(table->data, 0, sizeof(char)*32*32*32);
19736
19737
19738 data = (uint8_t *)table->data;
19739
19740 /* add starting seeds for floodfill */
19741 for(i=1; i<PAL_SIZE; i++)
19742 {
19743 curr = pos(pal[i].r, pal[i].g, pal[i].b);
19744
19745 if(next[curr] == UNUSED)
19746 {
19747 data[curr] = i;
19748 add(curr);
19749 }
19750 }
19751
19752 /* main floodfill: two versions of loop for faster growing in blue axis */
19753 // while (first != LAST) {
19754 while(first < LAST)
19755 {
19756 depos(first, r, g, b);
19757
19758 /* calculate distance of current color */
19759 val = data[first];
19760 r2 = (col_diff+128)[((pal[val].r)-(r)) & 0x7F];
19761 g2 = (col_diff)[((pal[val].g)-(g)) & 0x7F];
19762 b2 = (col_diff+256)[((pal[val].b)-(b)) & 0x7F];
19763
19764 /* try to grow to all directions */
19765 #ifdef _MSC_VER
19766 #pragma warning(disable:4127)
19767 #endif
19768 dopos(0, 0, 1, 1);
19769 dopos(0, 0,-1, 1);
19770 dopos(1, 0, 0, 1);
19771 dopos(-1, 0, 0, 1);
19772 dopos(0, 1, 0, 1);
19773 dopos(0,-1, 0, 1);
19774 #ifdef _MSC_VER
19775 #pragma warning(default:4127)
19776 #endif
19777
19778 /* faster growing of blue direction */
19779 if((b > 0) && (data[first-1] == val))
19780 {
19781 b -= 2;
19782 first--;
19783 b2 = (col_diff+256)[((pal[val].b)-(b)) & 0x7F];
19784
19785 #ifdef _MSC_VER
19786 #pragma warning(disable:4127)
19787 #endif
19788 dopos(-1, 0, 0, 0);
19789 dopos(1, 0, 0, 0);
19790 dopos(0,-1, 0, 0);
19791 dopos(0, 1, 0, 0);
19792 #ifdef _MSC_VER
19793 #pragma warning(default:4127)
19794 #endif
19795
19796 first++;
19797 }
19798
19799 /* get next from list */
19800 i = first;
19801 first = next[first];
19802 next[i] = UNUSED;
19803
19804 /* second version of loop */
19805 // if (first != LAST) {
19806 if(first < LAST)
19807 {
19808
19809 depos(first, r, g, b);
19810
19811 val = data[first];
19812 r2 = (col_diff+128)[((pal[val].r)-(r)) & 0x7F];
19813 g2 = (col_diff)[((pal[val].g)-(g)) & 0x7F];
19814 b2 = (col_diff+256)[((pal[val].b)-(b)) & 0x7F];
19815
19816 #ifdef _MSC_VER
19817 #pragma warning(disable:4127)
19818 #endif
19819 dopos(0, 0, 1, 1);
19820 dopos(0, 0,-1, 1);
19821 dopos(1, 0, 0, 1);
19822 dopos(-1, 0, 0, 1);
19823 dopos(0, 1, 0, 1);
19824 dopos(0,-1, 0, 1);
19825 #ifdef _MSC_VER
19826 #pragma warning(default:4127)
19827 #endif
19828
19829 if((b < 61) && (data[first + 1] == val))
19830 {
19831 b += 2;
19832 first++;
19833 b2 = (col_diff+256)[((pal[val].b)-(b)) & 0x7f];
19834 #ifdef _MSC_VER
19835 #pragma warning(disable:4127)
19836 #endif
19837 dopos(-1, 0, 0, 0);
19838 dopos(1, 0, 0, 0);
19839 dopos(0,-1, 0, 0);
19840 dopos(0, 1, 0, 0);
19841 #ifdef _MSC_VER
19842 #pragma warning(default:4127)
19843 #endif
19844
19845 first--;
19846 }
19847
19848 i = first;
19849 first = next[first];
19850 next[i] = UNUSED;
19851 }
19852
19853 count++;
19854
19855 if(count == (cbcount+1)*AVERAGE_COUNT/256)
19856 {
19857 if(cbcount < 256)
19858 {
19859 if(callback)
19860 callback(cbcount);
19861
19862 cbcount++;
19863 }
19864 }
19865
19866 }
19867
19868 /* only the transparent (pink) color can be mapped to index 0 */
19869 if((pal[0].r == 63) && (pal[0].g == 0) && (pal[0].b == 63))
19870 table->data[31][0][31] = 0;
19871
19872 if(callback)
19873 while(cbcount < 256)
19874 callback(cbcount++);
19875 }
19876
19877 11 void rebuild_trans_table()
19878 {
19879 11 refresh_rgb_tables();
19880 11 zq_rgb_table = rgb_table;
19881 11 }
19882
19883 int32_t isFullScreen()
19884 {
19885 return !is_windowed_mode();
19886 }
19887
19888 void hit_close_button()
19889 {
19890 close_button_quit=true;
19891 return;
19892 }
19893
19894 extern bool dirty_screen;
19895
19896 void anim_hw_screen()
19897 {
19898 ++cpoolbrush_index;
19899
19900 if(prv_mode)
19901 {
19902 if(Map.get_prvtime())
19903 {
19904 Map.set_prvtime(Map.get_prvtime()-1);
19905
19906 if(!Map.get_prvtime())
19907 {
19908 prv_warp=1;
19909 }
19910 }
19911 }
19912 if(AnimationOn)
19913 {
19914 animate_combos();
19915 update_freeform_combos();
19916 }
19917
19918 if(CycleOn)
19919 cycle_palette();
19920
19921 animate_coords();
19922 update_hw_screen();
19923 }
19924
19925 void custom_vsync()
19926 {
19927 anim_hw_screen();
19928 }
19929
19930 void switch_out()
19931 {
19932 zcmusic_pause(zcmusic, ZCM_PAUSE);
19933 zc_midi_pause();
19934 }
19935
19936 void switch_in()
19937 {
19938 if(exiting_program)
19939 return;
19940 zcmusic_pause(zcmusic, ZCM_RESUME);
19941 zc_midi_resume();
19942 }
19943
19944 void Z_eventlog(const char *format,...)
19945 {
19946 format=format; //to prevent a compiler warning
19947 }
19948
19949 int32_t get_currdmap()
19950 {
19951 return zinit.start_dmap;
19952 }
19953
19954 int32_t get_dlevel()
19955 {
19956 return DMaps[zinit.start_dmap].level;
19957 }
19958
19959 int32_t get_currscr()
19960 {
19961 return Map.getCurrScr();
19962 }
19963
19964 int32_t get_currmap()
19965 {
19966 return Map.getCurrMap();
19967 }
19968
19969 int32_t get_homescr()
19970 {
19971 return DMaps[zinit.start_dmap].cont;
19972 }
19973
19974 int get_screen_for_world_xy(int x, int y)
19975 {
19976 return -1;
19977 }
19978
19979 int current_item(int item_type, bool checkmagic, bool jinx_check, bool check_bunny)
19980 {
19981 //TODO remove as special case?? -DD
19982 if(item_type==itype_shield)
19983 {
19984 return 2;
19985 }
19986
19987 int id = current_item_id(item_type, checkmagic, jinx_check, check_bunny);
19988 return id > -1 ? itemsbuf[id].level : 0;
19989 }
19990
19991 int current_item_power(int itemtype, bool checkmagic, bool jinx_check, bool check_bunny)
19992 {
19993 if (game)
19994 {
19995 int result = current_item_id(itemtype, checkmagic, jinx_check, check_bunny);
19996 return (result<0) ? 0 : itemsbuf[result].power;
19997 }
19998 return 1;
19999 }
20000
20001 int32_t current_item_id(int32_t itemtype, bool, bool, bool)
20002 {
20003 if (game)
20004 {
20005 int32_t result = -1;
20006 int32_t highestlevel = -1;
20007
20008 for (int32_t i = 0; i < MAXITEMS; i++)
20009 {
20010 if ((zq_ignore_item_ownership || game->get_item(i)) && itemsbuf[i].type == itemtype)
20011 {
20012 if (itemsbuf[i].level >= highestlevel)
20013 {
20014 highestlevel = itemsbuf[i].level;
20015 result = i;
20016 }
20017 }
20018 }
20019 return result;
20020 }
20021 for(int32_t i=0; i<MAXITEMS; i++)
20022 {
20023 if(itemsbuf[i].type==itemtype)
20024 return i;
20025 }
20026
20027 return -1;
20028 }
20029
20030
20031 bool can_use_item(int32_t item_type, int32_t item)
20032 {
20033 //these are here to bypass compiler warnings about unused arguments
20034 item_type=item_type;
20035 item=item;
20036
20037 return true;
20038 }
20039
20040 bool has_item(int32_t item_type, int32_t it)
20041 {
20042 //these are here to bypass compiler warnings about unused arguments
20043 item_type=item_type;
20044 it=it;
20045
20046 return true;
20047 }
20048
20049 int32_t get_bmaps(int32_t si)
20050 {
20051 //these are here to bypass compiler warnings about unused arguments
20052 si=si;
20053
20054 return 255;
20055 }
20056
20057 bool no_subscreen()
20058 {
20059 return false;
20060 }
20061
20062 12 static void allocate_crap()
20063 {
20064 12 filepath=(char*)malloc(2048);
20065 12 datapath=(char*)malloc(2048);
20066 12 midipath=(char*)malloc(2048);
20067 12 imagepath=(char*)malloc(2048);
20068 12 tmusicpath=(char*)malloc(2048);
20069 12 last_timed_save=(char*)malloc(2048);
20070
20071
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(!filepath || !datapath || !imagepath || !midipath || !tmusicpath || !last_timed_save)
20072 {
20073 Z_error_fatal("Error: no memory for file paths!");
20074 }
20075
20076
20077 12 customtunes = (zctune*)malloc(sizeof(zctune)*MAXCUSTOMMIDIS_ZQ);
20078 12 memset(customtunes, 0, sizeof(zctune)*MAXCUSTOMMIDIS_ZQ);
20079
20080
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<MAXCUSTOMMIDIS_ZQ; ++i)
20081 {
20082 3072 customtunes[i].data=NULL;
20083 3072 }
20084
20085
2/2
✓ Branch 0 taken 3024 times.
✓ Branch 1 taken 12 times.
3036 for(int32_t i=0; i<MAXCUSTOMTUNES; i++)
20086 {
20087 3024 midi_string[i+4]=customtunes[i].title;
20088 3024 }
20089
20090
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<WAV_COUNT; i++)
20091 {
20092
1/4
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3072 if(sfx_string[i]!=NULL) delete sfx_string[i];
20093 3072 customsfxdata[i].data=NULL;
20094 3072 sfx_string[i] = new char[36];
20095 3072 memset(sfx_string[i], 0, 36);
20096 3072 }
20097
20098
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<MAXWPNS; i++)
20099 {
20100
1/4
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3072 if(weapon_string[i]!=NULL) delete weapon_string[i];
20101 3072 weapon_string[i] = new char[64];
20102 3072 memset(weapon_string[i], 0, 64);
20103 3072 }
20104
20105
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<MAXITEMS; i++)
20106 {
20107
1/4
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3072 if(item_string[i]!=NULL) delete item_string[i];
20108 3072 item_string[i] = new char[64];
20109 3072 memset(item_string[i], 0, 64);
20110 3072 }
20111
20112
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for(int32_t i=0; i<eMAXGUYS; i++)
20113 {
20114
1/4
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6144 if(guy_string[i]!=NULL) delete guy_string[i];
20115 6144 guy_string[i] = new char[64];
20116 6144 memset(guy_string[i], 0, 64);
20117 6144 }
20118
20119
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for(int32_t i=0; i<NUMSCRIPTFFC; i++)
20120 {
20121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6144 times.
6144 delete ffscripts[i];
20122
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 ffscripts[i] = new script_data(ScriptType::FFC, i);
20123 6144 }
20124
20125
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTITEM; i++)
20126 {
20127
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete itemscripts[i];
20128
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 itemscripts[i] = new script_data(ScriptType::Item, i);
20129 3072 }
20130
20131
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTGUYS; i++)
20132 {
20133
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete guyscripts[i];
20134
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 guyscripts[i] = new script_data(ScriptType::NPC, i);
20135 3072 }
20136
20137
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTSCREEN; i++)
20138 {
20139
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete screenscripts[i];
20140
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 screenscripts[i] = new script_data(ScriptType::Screen, i);
20141 3072 }
20142
20143
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 12 times.
108 for(int32_t i=0; i<NUMSCRIPTGLOBAL; i++)
20144 {
20145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 delete globalscripts[i];
20146
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 globalscripts[i] = new script_data(ScriptType::Global, i);
20147 96 }
20148
20149
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 12 times.
72 for(int32_t i=0; i<NUMSCRIPTHERO; i++)
20150 {
20151
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 delete playerscripts[i];
20152
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 playerscripts[i] = new script_data(ScriptType::Hero, i);
20153 60 }
20154
20155
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
20156 {
20157
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete lwpnscripts[i];
20158
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 lwpnscripts[i] = new script_data(ScriptType::Lwpn, i);
20159 3072 }
20160
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
20161 {
20162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3072 times.
3072 delete ewpnscripts[i];
20163
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 ewpnscripts[i] = new script_data(ScriptType::Ewpn, i);
20164 3072 }
20165
20166
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTSDMAP; i++)
20167 {
20168
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete dmapscripts[i];
20169
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 dmapscripts[i] = new script_data(ScriptType::DMap, i);
20170 3072 }
20171
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTSITEMSPRITE; i++)
20172 {
20173
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete itemspritescripts[i];
20174
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 itemspritescripts[i] = new script_data(ScriptType::ItemSprite, i);
20175 3072 }
20176
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for(int32_t i=0; i<NUMSCRIPTSCOMBODATA; i++)
20177 {
20178
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 delete comboscripts[i];
20179
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 comboscripts[i] = new script_data(ScriptType::Combo, i);
20180 6144 }
20181
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for(int32_t i=0; i<NUMSCRIPTSGENERIC; i++)
20182 {
20183
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 delete genericscripts[i];
20184
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 genericscripts[i] = new script_data(ScriptType::Generic, i);
20185 6144 }
20186
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTSSUBSCREEN; i++)
20187 {
20188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3072 times.
3072 delete subscreenscripts[i];
20189
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 subscreenscripts[i] = new script_data(ScriptType::EngineSubscreen, i);
20190 3072 }
20191 12 }
20192
20193 static void handle_sentry_tags()
20194 {
20195 static bool sentry_first_time = true;
20196
20197 static MapCursor sentry_last_map_cursor;
20198 if (Map.getCursor() != sentry_last_map_cursor || sentry_first_time)
20199 {
20200 sentry_last_map_cursor = Map.getCursor();
20201 zapp_reporting_set_tag("cursor.map", sentry_last_map_cursor.map);
20202 zapp_reporting_set_tag("cursor.screen", sentry_last_map_cursor.screen);
20203 zapp_reporting_set_tag("cursor.viewscr", sentry_last_map_cursor.viewscr);
20204 zapp_reporting_set_tag("cursor.size", sentry_last_map_cursor.size);
20205 }
20206
20207 static bool sentry_last_is_compact;
20208 if (is_compact != sentry_last_is_compact || sentry_first_time)
20209 {
20210 sentry_last_is_compact = is_compact;
20211 zapp_reporting_set_tag("compact", sentry_last_is_compact);
20212 }
20213
20214 sentry_first_time = false;
20215 }
20216
20217 int32_t Awpn=-1, Bwpn=-1, Xwpn = -1, Ywpn = -1;
20218 84 sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations, portals;
20219 int32_t exittimer = 10000, exittimer2 = 100;
20220
20221 template <typename ...Params>
20222 [[noreturn]] void FatalConsole(const char *format, Params&&... params)
20223 {
20224 FFCore.ZScriptConsole(CConsoleLoggerEx::COLOR_RED|CConsoleLoggerEx::COLOR_INTENSITY|CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"");
20225 Z_error_fatal(format, std::forward<Params>(params)...);
20226 }
20227
20228 5 static BITMAP* load_asset_bmp(const char* path)
20229 {
20230 5 BITMAP* bmp = load_bmp(path, nullptr);
20231
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (!bmp)
20232 Z_error_fatal("Failed to load required asset: %s\n", path);
20233 5 return bmp;
20234 }
20235
20236 1 static void load_asset_pal(PALETTE pal, const char* path)
20237 {
20238 1 BITMAP* bmp = load_bmp(path, pal);
20239
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!bmp)
20240 Z_error_fatal("Failed to load required asset: %s\n", path);
20241 1 }
20242
20243 1 static MIDI* load_asset_midi(const char* path)
20244 {
20245 1 MIDI* midi = load_midi(path);
20246
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!midi)
20247 Z_error_fatal("Failed to load required asset: %s\n", path);
20248 1 return midi;
20249 }
20250
20251 BITMAP* asset_icons_bmp;
20252 BITMAP* asset_engravings_bmp;
20253 BITMAP* asset_mouse_bmp;
20254 BITMAP* asset_select_bmp;
20255 BITMAP* asset_arrows_bmp;
20256 MIDI* asset_tunes_midi;
20257 PALETTE asset_pal;
20258
20259 1 static void load_assets()
20260 {
20261 1 asset_icons_bmp = load_asset_bmp("assets/editor/icons.bmp");
20262 1 asset_engravings_bmp = load_asset_bmp("assets/editor/engravings.bmp");
20263 1 asset_mouse_bmp = load_asset_bmp("assets/editor/mouse.bmp");
20264 1 asset_select_bmp = load_asset_bmp("assets/editor/select.bmp");
20265 1 asset_arrows_bmp = load_asset_bmp("assets/editor/arrows.bmp");
20266 1 asset_tunes_midi = load_asset_midi("assets/editor/tunes.mid");
20267 1 load_asset_pal(asset_pal, "assets/editor/pal.bmp");
20268 1 }
20269
20270 static bool application_has_loaded;
20271
20272 void do_dev_qrs_zscript_command(string const& fname);
20273
20274 1 int32_t main(int32_t argc,char **argv)
20275 {
20276
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (used_switch(argc, argv, "-test-zc"))
20277 1 set_headless_mode();
20278
20279 1 zalleg_setup_allegro(App::zquest, argc, argv);
20280 1 allocate_crap();
20281
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 set_should_zprint_cb([]() {
20282 return get_qr(qr_SCRIPTERRLOG) || DEVLEVEL > 0;
20283 });
20284
20285 1 Z_title("ZQuest Classic Editor, %s", getVersionString());
20286
20287
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!get_qst_buffers())
20288 {
20289 Z_error_fatal("Error");
20290 }
20291
20292 1 undocombobuf.clear();
20293 1 undocombobuf.resize(MAXCOMBOS);
20294
20295
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((newundotilebuf=(tiledata*)malloc(NEWMAXTILES*sizeof(tiledata)))==NULL)
20296 {
20297 Z_error_fatal("Error: no memory for tile undo buffer!");
20298 }
20299
20300 1 memset(newundotilebuf, 0, NEWMAXTILES*sizeof(tiledata));
20301 1 newtilebuf = (tiledata*)malloc(NEWMAXTILES*sizeof(tiledata));
20302
20303
2/2
✓ Branch 0 taken 2574000 times.
✓ Branch 1 taken 1 times.
2574001 for(int32_t j=0; j<NEWMAXTILES; j++)
20304 2574000 newtilebuf[j].data=NULL;
20305
20306 1 zc_srand(time(0));
20307
20308 1 zeditor_handle_commands();
20309
20310 1 three_finger_flag=false;
20311
20312 #ifndef __EMSCRIPTEN__
20313
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(zc_get_config("zquest","open_debug_console",0))
20314 initConsole();
20315 #endif
20316
20317 LOCK_VARIABLE(lastfps);
20318
20319 LOCK_VARIABLE(framecnt);
20320 LOCK_FUNCTION(fps_callback);
20321
20322
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(install_int_ex(fps_callback,SECS_TO_TIMER(1)))
20323 {
20324 Z_error_fatal("couldn't allocate timer");
20325 }
20326
20327
20328 LOCK_VARIABLE(dclick_status);
20329 LOCK_VARIABLE(dclick_time);
20330 1 lock_dclick_function();
20331 1 install_int(dclick_check, 20);
20332
20333 1 set_gfx_mode(GFX_TEXT,80,50,0,0);
20334
20335 1 load_assets();
20336
20337 1 Z_message("OK\n");
20338
20339
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 helpstr = util::read_text_file("docs/zquest.txt");
20340
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 zstringshelpstr = util::read_text_file("docs/zstrings.txt");
20341
20342 // loading data files...
20343
20344 1 filepath[0]=temppath[0]=0;
20345
20346 1 const char *default_path="";
20347
20348 1 strcpy(datapath,zc_get_config("zquest",data_path_name,default_path));
20349 1 strcpy(midipath,zc_get_config("zquest",midi_path_name,default_path));
20350 1 strcpy(imagepath,zc_get_config("zquest",image_path_name,default_path));
20351 1 strcpy(tmusicpath,zc_get_config("zquest",tmusic_path_name,default_path));
20352 1 chop_path(datapath);
20353 1 chop_path(midipath);
20354 1 chop_path(imagepath);
20355 1 chop_path(tmusicpath);
20356
20357 1 DisableLPalShortcuts = zc_get_config("zquest","dis_lpal_shortcut",1);
20358 1 DisableCompileConsole = zc_get_config("zquest","internal_compile_console",0);
20359 1 MouseScroll = zc_get_config("zquest","mouse_scroll",0);
20360 1 MMapCursorStyle = zc_get_config("zquest","cursorblink_style",1);
20361 1 LayerDitherBG = zc_get_config("zquest", "layer_dither_bg", -1);
20362 1 LayerDitherSz = zc_get_config("zquest", "layer_dither_sz", 3);
20363 1 InvalidBG = zc_get_config("zquest", "invalid_bg", 0);
20364 1 TileProtection = zc_get_config("zquest","tile_protection",1);
20365 1 ComboProtection = zc_get_config("zquest","combo_protection",TileProtection);
20366 1 ShowGrid = zc_get_config("zquest","show_grid",0);
20367 1 ShowCurScreenOutline = zc_get_config("zquest","show_current_screen_outline",1);
20368 1 ShowScreenGrid = zc_get_config("zquest","show_screen_grid",0);
20369 1 ShowRegionGrid = zc_get_config("zquest","show_region_grid",1);
20370 1 HighQualityScreenRendering = zc_get_config("zquest","high_quality_screen_rendering",1);
20371 1 GridColor = zc_get_config("zquest","grid_color",15);
20372 1 CmbCursorCol = zc_get_config("zquest","combo_cursor_color",15);
20373 1 TilePgCursorCol = zc_get_config("zquest","tpage_cursor_color",15);
20374 1 CmbPgCursorCol = zc_get_config("zquest","cpage_cursor_color",15);
20375 1 TTipHLCol = zc_get_config("zquest","ttip_hl_color",13);
20376 1 CheckerCol1 = zc_get_config("zquest","checker_color_1",7);
20377 1 CheckerCol2 = zc_get_config("zquest","checker_color_2",8);
20378 1 SnapshotFormat = zc_get_config("zquest","snapshot_format",3);
20379 1 SnapshotScale = zc_get_config("zquest","snapshot_scale",2);
20380 1 SavePaths = zc_get_config("zquest","save_paths",1);
20381 1 CycleOn = zc_get_config("zquest","cycle_on",1);
20382 1 ShowFPS = zc_get_config("zquest","showfps",0)!=0;
20383 1 SaveDragResize = zc_get_config("zquest","save_drag_resize",0)!=0;
20384 1 DragAspect = zc_get_config("zquest","drag_aspect",0)!=0;
20385 1 SaveWinPos = zc_get_config("zquest","save_window_position",0)!=0;
20386 1 ComboBrush = zc_get_config("zquest","combo_brush",0);
20387 1 FloatBrush = zc_get_config("zquest","float_brush",0);
20388 1 AutoBrush = zc_get_config("zquest","autobrush",1);
20389 1 LinkedScroll = zc_get_config("zquest","linked_comboscroll",0);
20390 1 allowHideMouse = zc_get_config("ZQ_GUI","allowHideMouse",0);
20391 1 ShowFavoriteComboModes = zc_get_config("ZQ_GUI","show_fav_combo_modes",1);
20392 1 NoHighlightLayer0 = zc_get_config("zquest","no_highlight_layer0",0);
20393 1 RulesetDialog = zc_get_config("zquest","rulesetdialog",1);
20394 1 EnableTooltips = zc_get_config("zquest","enable_tooltips",1);
20395 1 TooltipsHighlight = zc_get_config("zquest","ttip_highlight",1);
20396 1 tooltip_maxtimer = vbound(zc_get_config("zquest","ttip_timer",30),0,60*60);
20397 1 ShowFFScripts = zc_get_config("zquest","showffscripts",1);
20398 1 ShowSquares = zc_get_config("zquest","showsquares",1);
20399 1 ShowFFCs = zc_get_config("zquest","showffcs",0);
20400 1 ShowInfo = zc_get_config("zquest","showinfo",1);
20401 1 skipLayerWarning = zc_get_config("zquest","skip_layer_warning",0);
20402 1 numericalFlags = zc_get_config("zquest","numerical_flags",0);
20403 1 ViewLayer2BG = zc_get_config("zquest","layer2_bg",0);
20404 1 ViewLayer3BG = zc_get_config("zquest","layer3_bg",0);
20405 1 ActiveLayerHighlight = zc_get_config("zquest","hl_active_lyr",0);
20406 1 DragCenterOfSquares = zc_get_config("zquest","drag_squares_from_center",0);
20407 1 SmartFFCPlacement = zc_get_config("zquest","smart_ffc_placement",0);
20408
20409 1 OpenLastQuest = zc_get_config("zquest","open_last_quest",0);
20410 1 ShowMisalignments = zc_get_config("zquest","show_misalignments",0);
20411 1 AnimationOn = zc_get_config("zquest","animation_on",1);
20412 1 AutoBackupRetention = zc_get_config("zquest","auto_backup_retention",2);
20413 1 AutoSaveInterval = zc_get_config("zquest","auto_save_interval",6);
20414 1 AutoSaveRetention = zc_get_config("zquest","auto_save_retention",2);
20415 1 UncompressedAutoSaves = zc_get_config("zquest","uncompressed_auto_saves",1);
20416 1 OverwriteProtection = zc_get_config("zquest","overwrite_prevention",0)!=0;
20417 1 ImportMapBias = zc_get_config("zquest","import_map_bias",0);
20418
20419 1 KeyboardRepeatDelay = zc_get_config("zquest","keyboard_repeat_delay",300);
20420 1 KeyboardRepeatRate = zc_get_config("zquest","keyboard_repeat_rate",80);
20421
20422 // Frameskip = zc_get_config("zquest","frameskip",0); //todo: this is not actually supported yet.
20423 1 RequestedFPS = zc_get_config("zquest","fps",60);
20424
20425 // Autofill for Combo Page, Tile Page
20426 1 PreFillTileEditorPage = zc_get_config("zquest","PreFillTileEditorPage",0);
20427 1 PreFillComboEditorPage = zc_get_config("zquest","PreFillComboEditorPage",0);
20428
20429 1 pixeldb = zc_get_config("ZQ_GUI","bottom_8_pixels",0);
20430 1 infobg = zc_get_config("ZQ_GUI","info_text_bg",0);
20431
20432 1 large_merged_combopane = zc_get_config("ZQ_GUI","merge_cpane_large",0);
20433 1 compact_merged_combopane = zc_get_config("ZQ_GUI","merge_cpane_compact",1);
20434
20435 1 compact_square_panels = zc_get_config("ZQ_GUI","square_panels_compact",0);
20436
20437 1 large_zoomed_fav = zc_get_config("ZQ_GUI","zoom_fav_large",0);
20438 1 compact_zoomed_fav = zc_get_config("ZQ_GUI","zoom_fav_compact",1);
20439 1 large_zoomed_cmd = zc_get_config("ZQ_GUI","zoom_cmd_large",1);
20440 1 compact_zoomed_cmd = zc_get_config("ZQ_GUI","zoom_cmd_compact",1);
20441
20442
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(zc_get_config("gui","disable_window_resizing",0))
20443 all_set_resize_flag(false);
20444
20445 1 load_hotkeys();
20446
20447 #ifdef _WIN32
20448 zqUseWin32Proc = zc_get_config("zquest","zq_win_proc_fix",0);
20449
20450 #endif
20451
20452
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!render_timer_start())
20453 {
20454 Z_error_fatal("couldn't allocate timer");
20455 }
20456
20457 1 byte layermask = zc_get_config("zquest","layer_mask",0x7F);
20458 1 int32_t usefullscreen = zc_get_config("zquest","fullscreen",0);
20459 1 tempmode = (usefullscreen == 0 ? GFX_AUTODETECT_WINDOWED : GFX_AUTODETECT_FULLSCREEN);
20460
20461
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 for(int32_t x=0; x<7; x++)
20462 {
20463 7 LayerMaskInt[x]=get_bit(&layermask,x);
20464 7 }
20465
20466 1 DuplicateAction[0] = zc_get_config("zquest","normal_duplicate_action",2);
20467 1 DuplicateAction[1] = zc_get_config("zquest","horizontal_duplicate_action",0);
20468 1 DuplicateAction[2] = zc_get_config("zquest","vertical_duplicate_action",0);
20469 1 DuplicateAction[3] = zc_get_config("zquest","both_duplicate_action",0);
20470 1 LeechUpdate = zc_get_config("zquest","leech_update",500);
20471 1 LeechUpdateTiles = zc_get_config("zquest","leech_update_tiles",1);
20472 1 OnlyCheckNewTilesForDuplicates = zc_get_config("zquest","only_check_new_tiles_for_duplicates",0);
20473 //gui_colorset = zc_get_config("zquest","gui_colorset",0);
20474
20475 1 strcpy(last_timed_save,zc_get_config("zquest","last_timed_save",""));
20476
20477 1 midi_volume = zc_get_config("zquest", "midi", 255);
20478
20479 1 abc_patternmatch = zc_get_config("zquest", "lister_pattern_matching", 1);
20480 1 NoScreenPreview = zc_get_config("zquest", "no_preview", 0);
20481
20482 1 monochrome_console = zc_get_config("CONSOLE","monochrome_debuggers",0)?1:0;
20483
20484 1 try_recovering_missing_scripts = 0;//zc_get_config("Compiler", "try_recovering_missing_scripts",0);
20485 //We need to remove all of the zeldadx refs to the config file for zquest.
20486
20487 1 set_keyboard_rate(KeyboardRepeatDelay,KeyboardRepeatRate);
20488
20489 1 is_compact = zc_get_config("ZQ_GUI","compact_mode",1);
20490 1 mapscreenbmp = nullptr;
20491 1 brushbmp = nullptr;
20492 1 brushscreen = nullptr;
20493 1 screen2 = nullptr;
20494
20495
2/2
✓ Branch 0 taken 1260 times.
✓ Branch 1 taken 1 times.
1261 for(int32_t i=0; i<MAXFAVORITECOMBOS; ++i)
20496 {
20497 1260 favorite_combos[i]=-1;
20498 1260 }
20499 1 FavoriteComboPage = 0;
20500
20501
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(used_switch(argc,argv,"-d"))
20502 {
20503 set_debug(!strcmp(zquestpwd,zc_get_config("zquest","debug_this","")));
20504 }
20505
20506 1 zcmusic_init();
20507 1 zcmixer = zcmixer_create();
20508 24 install_int_ex([](){ zcmusic_poll(); }, MSEC_TO_TIMER(25));
20509
20510 1 set_color_depth(8);
20511
20512 1 set_close_button_callback((void (*)()) hit_close_button);
20513
20514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(used_switch(argc,argv,"-fullscreen"))
20515 {
20516 tempmode = GFX_AUTODETECT_FULLSCREEN;
20517 }
20518
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 else if(used_switch(argc,argv,"-windowed"))
20519 {
20520 tempmode=GFX_AUTODETECT_WINDOWED;
20521 }
20522
20523 1 zq_screen_w = LARGE_W;
20524 1 zq_screen_h = LARGE_H;
20525 1 window_width = zc_get_config("zquest","window_width",-1);
20526 1 window_height = zc_get_config("zquest","window_height",-1);
20527 1 auto [w, h] = zc_get_default_display_size(LARGE_W, LARGE_H, window_width, window_height);
20528
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 int32_t videofail = is_headless() ? 0 : (set_gfx_mode(tempmode,w,h,zq_screen_w,zq_screen_h));
20529
20530 //extra block here is intentional
20531
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(videofail!=0)
20532 {
20533 quit_game();
20534 allegro_exit();
20535 }
20536
20537 1 zalleg_create_window();
20538 1 Z_message("gfx mode set at -%d %dbpp %d x %d \n",
20539 1 tempmode, get_color_depth(), zq_screen_w, zq_screen_h);
20540
20541 1 set_window_title("ZC Editor");
20542
20543 1 load_size_poses();
20544
20545
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!is_headless())
20546 {
20547 // Just in case.
20548 while (!all_get_display()) {
20549 al_rest(1);
20550 }
20551
20552 al_resize_display(all_get_display(), w, h);
20553 }
20554
20555
20556 #ifndef __EMSCRIPTEN__
20557
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (!all_get_fullscreen_flag() && !is_headless()) {
20558 al_resize_display(all_get_display(), w, h);
20559
20560 int window_w = al_get_display_width(all_get_display());
20561 int window_h = al_get_display_height(all_get_display());
20562
20563 int new_x = zc_get_config("zquest","window_x",0);
20564 int new_y = zc_get_config("zquest","window_y",0);
20565 if(zc_get_config("zquest","save_window_position",0) && (new_x || new_y))
20566 {
20567 //load saved position
20568 //already stored in new_x/new_y
20569 }
20570 else
20571 {
20572 //Get default position
20573 ALLEGRO_MONITOR_INFO info;
20574 al_get_monitor_info(0, &info);
20575
20576 int mw = (info.x2 - info.x1);
20577 int mh = (info.y2 - info.y1);
20578 new_x = mw / 2 - window_w / 2;
20579 new_y = mh / 2 - window_h / 2;
20580 //Don't spawn the window too far down (taskbar?)
20581 if(new_y + window_h > mh - 72)
20582 new_y = mh-72-window_h;
20583 }
20584 #ifdef ALLEGRO_MACOSX
20585 if (zc_get_config("zquest","save_window_position",0))
20586 al_set_window_position(all_get_display(), new_x, new_y);
20587 #else
20588 al_set_window_position(all_get_display(), new_x, new_y);
20589 #endif
20590 }
20591 #endif
20592
20593 1 position_mouse(zq_screen_w/2,zq_screen_h/2);
20594
20595 1 dmapbmp_small = create_bitmap_ex(8,65,33);
20596 1 dmapbmp_large = create_bitmap_ex(8,177,81);
20597
20598
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!screen2 || !dmapbmp_large || !dmapbmp_large || !brushbmp || !brushscreen)// || !brushshadowbmp )
20599 {
20600 Z_error_fatal("Failed to create system bitmaps!\n");
20601 return 1;
20602 }
20603
20604
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!is_headless())
20605 {
20606 zc_set_palette(asset_pal);
20607 get_palette(RAMpal);
20608 load_colorset(gui_colorset);
20609 zc_set_palette(RAMpal);
20610 clear_to_color(screen,vc(0));
20611 }
20612
20613 1 zScript = string();
20614 1 strcpy(zScriptBytes, "0 Bytes in Buffer");
20615
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
13 for(int32_t i=0; i<MOUSE_BMP_MAX; i++)
20616 {
20617
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 12 times.
60 for(int32_t j=0; j<4; j++)
20618 {
20619 48 mouse_bmp[i][j] = NULL;
20620 48 mouse_bmp_1x[i][j] = NULL;
20621 48 }
20622 12 }
20623 1 load_mice();
20624 1 gui_mouse_focus=0;
20625 1 MouseSprite::set(ZQM_NORMAL);
20626 1 render_zq(); // Ensure the rendering bitmaps are setup.
20627
20628 #ifdef __EMSCRIPTEN__
20629 em_mark_ready_status();
20630 #endif
20631
20632 1 load_icons();
20633
20634 1 bool load_last_timed_save=false;
20635
20636 1 load_recent_quests();
20637 1 refresh_recent_menu();
20638 //clearConsole();
20639
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if((last_timed_save[0]!=0)&&(exists(last_timed_save)))
20640 {
20641 if (alert_confirm("ZQuest","It appears that ZQuest crashed last time.\nWould you like to load the last timed save?"))
20642 {
20643 int32_t ret = load_quest(last_timed_save);
20644
20645 if(ret == qe_OK)
20646 {
20647 strcpy(filepath,last_timed_save);
20648 load_last_timed_save=true;
20649 mark_save_dirty();
20650 }
20651 else
20652 {
20653 displayinfo("Error","Unable to reload the last timed save.");
20654 }
20655 }
20656 }
20657
20658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!load_last_timed_save)
20659 {
20660 1 strcpy(filepath,zc_get_config("zquest",last_quest_name,""));
20661
20662
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if(argc>1 && argv[1][0]!='-')
20663 {
20664 int32_t ret = load_quest(argv[1]);
20665
20666 if(ret == qe_OK)
20667 {
20668 first_save=true;
20669 strcpy(filepath,argv[1]);
20670 refresh(rALL);
20671 }
20672 }
20673
2/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 else if(OpenLastQuest&&filepath[0]&&exists(filepath)&&!used_switch(argc,argv,"-new"))
20674 {
20675 int32_t ret = load_quest(filepath);
20676
20677 if(ret == qe_OK)
20678 {
20679 first_save=true;
20680 refresh(rALL);
20681 }
20682 else
20683 {
20684 filepath[0]=temppath[0]=0;
20685 first_save=false;
20686 }
20687 }
20688 else
20689 {
20690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (onNew() == D_CLOSE)
20691 {
20692 1 Z_message("User canceled creating new quest, closing.\n");
20693 1 exit(0);
20694 }
20695
20696 //otherwise the blank quest gets the name of the last loaded quest... not good! -DD
20697 filepath[0]=temppath[0]=0;
20698 first_save=false;
20699 }
20700 }
20701
20702 if(used_switch(argc,argv,"-q"))
20703 {
20704 Z_message("-q switch used, quitting program.\n");
20705 zq_exit(0);
20706 }
20707
20708 for(int32_t x=0; x<MAXITEMS; x++)
20709 {
20710 lens_hint_item[x][0]=0;
20711 lens_hint_item[x][1]=0;
20712 }
20713
20714 for(int32_t x=0; x<MAXWPNS; x++)
20715 {
20716 lens_hint_weapon[x][0]=0;
20717 lens_hint_weapon[x][1]=0;
20718 }
20719
20720 load_selections();
20721 load_arrows();
20722 DIALOG_PLAYER *player2=init_dialog(dialogs,-1);
20723
20724 get_palette(RAMpal);
20725
20726 rgb_map = zq_rgb_table;
20727
20728 #ifdef __EMSCRIPTEN__
20729 {
20730 int qs_map = EM_ASM_INT({
20731 return new URL(location.href).searchParams.get('map') ?? -1;
20732 });
20733 int qs_screen = EM_ASM_INT({
20734 return new URL(location.href).searchParams.get('screen') ?? -1;
20735 });
20736 if (qs_map != -1 && qs_screen != -1) {
20737 Map.setCurrMap(qs_map);
20738 Map.setCurrScr(qs_screen);
20739 }
20740 }
20741 #endif
20742
20743 // setup_combo_animations();
20744 pause_refresh = false;
20745 refresh_pal();
20746 refresh(rALL);
20747 for(int q = 0; q < brush_width_menu.size(); ++q)
20748 brush_width_menu.at(q)->select(q==0);
20749 for(int q = 0; q < brush_height_menu.size(); ++q)
20750 brush_height_menu.at(q)->select(q==0);
20751 set_filltype(1);
20752
20753 rebuild_trans_table();
20754
20755 if (!is_headless())
20756 {
20757 set_display_switch_mode(SWITCH_BACKGROUND);
20758 set_display_switch_callback(SWITCH_OUT, switch_out);
20759 set_display_switch_callback(SWITCH_IN, switch_in);
20760 }
20761
20762 if(!update_dialog(player2))
20763 exiting_program = true;
20764 //clear_keybuf();
20765 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, true);
20766 disable_hotkey(ZQKEY_CHANGE_TRACK, true);
20767
20768 fix_drawing_mode_menu();
20769
20770
20771 #ifdef _WIN32
20772
20773 if(zqUseWin32Proc != FALSE)
20774 {
20775 al_trace("Config file warning: \"zq_win_proc_fix\" enabled switch found. This can cause crashes on some computers.\n");
20776 win32data.zqSetDefaultThreadPriority(0);
20777 win32data.zqSetCustomCallbackProc(al_get_win_window_handle(all_get_display()));
20778 }
20779
20780 #endif
20781
20782 time(&auto_save_time_start);
20783
20784 FFCore.init();
20785 ZQincludePaths = FFCore.includePaths;
20786
20787 Map.setCopyFFC(-1); //Do not have an initial ffc on the clipboard.
20788 brush_menu.select_uid(MENUID_BRUSH_AUTOBRUSH, AutoBrush);
20789 brush_menu.disable_uid(MENUID_BRUSH_WIDTH, AutoBrush);
20790 brush_menu.disable_uid(MENUID_BRUSH_HEIGHT, AutoBrush);
20791 brush_menu.select_uid(MENUID_BRUSH_COMBOBRUSH, ComboBrush);
20792 brush_menu.select_uid(MENUID_BRUSH_FLOATBRUSH, FloatBrush);
20793
20794 application_has_loaded = true;
20795
20796 while(!exiting_program)
20797 {
20798 handle_sentry_tags();
20799
20800 #ifdef _WIN32
20801 if(zqUseWin32Proc != FALSE)
20802 win32data.Update(Frameskip); //experimental win32 fixes
20803 #endif
20804 check_autosave();
20805 ++alignment_arrow_timer;
20806
20807 if(alignment_arrow_timer>63)
20808 {
20809 alignment_arrow_timer=0;
20810 }
20811 ++frame;
20812
20813 file_menu.disable_uid(MENUID_FILE_SAVE, saved||disable_saving||OverwriteProtection);
20814 file_menu.disable_uid(MENUID_FILE_REVERT, saved||disable_saving||OverwriteProtection);
20815 file_menu.disable_uid(MENUID_FILE_SAVEAS, disable_saving);
20816
20817 fixtools_menu.disable_uid(MENUID_FIXTOOL_OLDSTRING,
20818 !(get_qr(qr_OLD_STRING_EDITOR_MARGINS)
20819 ||get_qr(qr_STRING_FRAME_OLD_WIDTH_HEIGHT)));
20820
20821 edit_menu.disable_uid(MENUID_EDIT_UNDO, !Map.CanUndo());
20822 edit_menu.disable_uid(MENUID_EDIT_REDO, !Map.CanRedo());
20823
20824 bool canpaste = Map.CanPaste();
20825 edit_menu.disable_uid(MENUID_EDIT_PASTE, !canpaste);
20826 edit_menu.disable_uid(MENUID_EDIT_PASTEALL, !canpaste);
20827 edit_menu.disable_uid(MENUID_EDIT_ADVPASTE, !canpaste);
20828 edit_menu.disable_uid(MENUID_EDIT_SPECPASTE, !canpaste);
20829 rc_menu_screen.disable_uid(MENUID_RCSCREEN_PASTE, !canpaste);
20830 rc_menu_screen.disable_uid(MENUID_RCSCREEN_ADVPASTE, !canpaste);
20831 rc_menu_screen.disable_uid(MENUID_RCSCREEN_SPECPASTE, !canpaste);
20832 for(MenuItem& mit : paste_menu.inner())
20833 mit.disable(!canpaste);
20834 for(MenuItem& mit : paste_item_menu.inner())
20835 mit.disable(!canpaste);
20836
20837 edit_menu.disable_uid(MENUID_EDIT_COPY, !(Map.CurrScr()->valid&mVALID));
20838 edit_menu.disable_uid(MENUID_EDIT_DELETE, !(Map.CurrScr()->valid&mVALID));
20839
20840 // Are some things selected?
20841 view_menu.select_uid(MENUID_VIEW_WALKABILITY, Flags&cWALK);
20842 view_menu.select_uid(MENUID_VIEW_FLAGS, Flags&cFLAGS);
20843 view_menu.select_uid(MENUID_VIEW_CSET, Flags&cCSET);
20844 view_menu.select_uid(MENUID_VIEW_TYPES, Flags&cCTYPE);
20845 view_menu.select_uid(MENUID_VIEW_INFO, ShowInfo);
20846 view_menu.select_uid(MENUID_VIEW_SQUARES, ShowSquares);
20847 view_menu.select_uid(MENUID_VIEW_FFCS, ShowFFCs);
20848 view_menu.select_uid(MENUID_VIEW_SCRIPTNAMES, ShowFFScripts);
20849 view_menu.select_uid(MENUID_VIEW_GRID, ShowGrid);
20850 view_menu.select_uid(MENUID_VIEW_SCREENGRID, ShowScreenGrid);
20851 view_menu.select_uid(MENUID_VIEW_REGIONGRID, ShowRegionGrid);
20852 view_menu.select_uid(MENUID_VIEW_CURSCROUTLINE, ShowCurScreenOutline);
20853 view_menu.select_uid(MENUID_VIEW_DARKNESS, get_qr(qr_NEW_DARKROOM) && (Flags&cNEWDARK));
20854 view_menu.select_uid(MENUID_VIEW_L2BG, ViewLayer2BG);
20855 view_menu.select_uid(MENUID_VIEW_L3BG, ViewLayer3BG);
20856 view_menu.select_uid(MENUID_VIEW_LAYERHIGHLIGHT, ActiveLayerHighlight);
20857 view_menu.select_uid(MENUID_VIEW_HIGH_QUALITY_SCREEN_RENDERING, HighQualityScreenRendering);
20858
20859 maps_menu.disable_uid(MENUID_MAPS_NEXT, !map_count || Map.getCurrMap() >= map_count);
20860 maps_menu.disable_uid(MENUID_MAPS_PREV, Map.getCurrMap()<=0);
20861
20862 etc_menu.disable_uid(MENUID_ETC_VIDMODE, isFullScreen()==1);
20863 etc_menu.select_uid(MENUID_ETC_FULLSCREEN, isFullScreen()==1);
20864
20865 if(!update_dialog(player2))
20866 exiting_program = true;
20867
20868 //clear_keybuf();
20869 handle_close_btn_quit();
20870 }
20871
20872 zq_exit(0);
20873 return 0;
20874 }
20875 END_OF_MAIN()
20876
20877 11 void zq_exit(int code)
20878 {
20879 11 set_is_exiting();
20880 11 parser_console.kill();
20881 11 killConsole();
20882
20883 11 quit_game();
20884 11 allegro_exit();
20885 11 exit(code);
20886 }
20887
20888 4 void init_bitmap(BITMAP** bmp, int32_t w, int32_t h)
20889 {
20890
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(*bmp)
20891 destroy_bitmap(*bmp);
20892 4 *bmp = create_bitmap_ex(8,w,h);
20893 4 clear_bitmap(*bmp);
20894 4 }
20895 1 void load_size_poses()
20896 {
20897 1 ttip_uninstall_all();
20898
20899 1 FONT* favcmdfont = get_custom_font(CFONT_FAVCMD);
20900 1 FONT* guifont = get_custom_font(CFONT_GUI);
20901
20902 1 d_nbmenu_proc(MSG_START, &dialogs[0], 0);
20903
20904 1 commands_list.xscale = command_buttonwidth;
20905 1 commands_list.yscale = 10+text_height(favcmdfont);
20906
20907 1 auto drawmode_wid = 64;
20908
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 for(auto q = 0; q < dm_max; ++q)
20909 {
20910 6 auto wid = text_length(guifont, dm_names[q]);
20911
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(wid > drawmode_wid)
20912 drawmode_wid = wid;
20913 6 }
20914
20915 //Main GUI objects
20916
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(is_compact)
20917 {
20918 1 num_combo_cols = 2;
20919 1 combo_col_scale = 16;
20920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(compact_merged_combopane)
20921 {
20922 1 num_combo_cols = 1;
20923 1 combo_col_scale = 32;
20924 1 }
20925
20926 1 mapscreen_x=0;
20927 1 mapscreen_y=dialogs[0].h;
20928 1 mapscreen_screenunit_scale=3;
20929 1 mapscreen_single_scale = (double)mapscreen_screenunit_scale / Map.getViewSize();
20930 1 showedges=0;
20931 1 showallpanels=0;
20932
20933 1 blackout_color=8;
20934
20935 1 auto mapscr_wid = (((showedges?2:0)+16)*16*mapscreen_screenunit_scale);
20936 1 combolist_window.w=zq_screen_w-mapscr_wid;
20937 1 combolist_window.x=zq_screen_w-combolist_window.w;
20938
20939 1 favorites_window.x=combolist_window.x;
20940 1 favorites_window.w=combolist_window.w;
20941 1 favorites_window.h=136;
20942 1 favorites_window.y=zq_screen_h-favorites_window.h;
20943
20944 1 combolist_window.y=0;
20945 1 combolist_window.h=favorites_window.y-combolist_window.y;
20946
20947 1 combo_preview.x=zq_screen_w-32-8;
20948 1 combo_preview.y=combolist_window.y+6;
20949 1 combo_preview.w=32;
20950 1 combo_preview.h=32;
20951 1 combo_preview2.clear();
20952
20953 1 auto col_wid = 4*combo_col_scale;
20954 1 auto cols_wid = col_wid * num_combo_cols;
20955 1 auto cols_spacing = (combolist_window.w-cols_wid)/(num_combo_cols+1);
20956
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for(auto q = 0; q < num_combo_cols; ++q)
20957 {
20958 1 combolist[q].x=combolist_window.x+(cols_spacing*(q+1))+(col_wid*q);
20959 1 combolist[q].y=combolist_window.y+54;
20960 1 combolist[q].w=4;
20961 1 combolist[q].h=compact_merged_combopane ? 15 : 30;
20962 1 combolist[q].xscale = combo_col_scale;
20963 1 combolist[q].yscale = combo_col_scale;
20964
20965 1 comboaliaslist[q].x = combolist[q].x;
20966 1 comboaliaslist[q].y = combolist[q].y;
20967 1 comboaliaslist[q].w = 4;
20968 1 comboaliaslist[q].h = compact_merged_combopane ? 13 : 26;
20969 1 comboaliaslist[q].xscale = combo_col_scale;
20970 1 comboaliaslist[q].yscale = combo_col_scale;
20971
20972 1 combolistscrollers[q].w=2;
20973 1 combolistscrollers[q].h=1;
20974 1 combolistscrollers[q].xscale=11;
20975 1 combolistscrollers[q].yscale=11;
20976 1 combolistscrollers[q].x=combolist[q].x+(combolist[q].w*combolist[q].xscale/2)-11;
20977 1 combolistscrollers[q].y=combolist[q].y-combolistscrollers[q].th()-3;
20978 1 }
20979
20980 1 comboalias_preview.x=zq_screen_w-((combolist_window.w+64)/2);
20981 1 comboalias_preview.h=64;
20982 1 comboalias_preview.y=favorites_window.y-comboalias_preview.h-8;
20983 1 comboalias_preview.w=64;
20984
20985 1 combo_merge_btn.w = 20;
20986 1 combo_merge_btn.h = 20;
20987 1 combo_merge_btn.x = zq_screen_w-(combolist_window.w+combo_merge_btn.w)/2;
20988 1 combo_merge_btn.y = combolist[0].y-combo_merge_btn.h;
20989
20990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(num_combo_cols == 1)
20991 {
20992 1 combolistscrollers[0].x += 34;
20993 1 }
20994 1 drawmode_btn.x = combolist_window.x-drawmode_wid;
20995 1 drawmode_btn.y = 0;
20996 1 drawmode_btn.w = drawmode_wid;
20997 1 drawmode_btn.h = mapscreen_y;
20998
20999 1 compactbtn.w = text_length(guifont,"> Compact")+10;
21000 1 compactbtn.x = drawmode_btn.x-compactbtn.w;
21001 1 compactbtn.y = drawmode_btn.y;
21002 1 compactbtn.h = drawmode_btn.h;
21003
21004 1 zoominbtn.w = text_length(guifont,"+")+10;
21005 1 zoominbtn.x = compactbtn.x-zoominbtn.w;
21006 1 zoominbtn.y = compactbtn.y;
21007 1 zoominbtn.h = compactbtn.h;
21008
21009 1 zoomoutbtn.w = text_length(guifont,"-")+10;
21010 1 zoomoutbtn.x = zoominbtn.x-zoomoutbtn.w;
21011 1 zoomoutbtn.y = compactbtn.y;
21012 1 zoomoutbtn.h = compactbtn.h;
21013
21014
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 for(int32_t i=0; i<=8; i++)
21015 {
21016 9 map_page_bar[i].w = 48;
21017 9 map_page_bar[i].x = mapscreen_x+(i*48);
21018 9 map_page_bar[i].y = mapscreen_y+(11*16*mapscreen_screenunit_scale);
21019 9 map_page_bar[i].h = text_height(guifont)+12;
21020 9 }
21021
21022 1 minimap.w=7+48*3;
21023 1 minimap.h=16+27*3;
21024
21025 1 layer_panel.x=map_page_bar[6].x;
21026 1 layer_panel.y=map_page_bar[0].y;
21027 1 layer_panel.w=combolist_window.x - layer_panel.x;
21028 1 layer_panel.h=map_page_bar[0].h;
21029 1 layerpanel_buttonwidth = 51;
21030 1 layerpanel_buttonheight = layer_panel.h;
21031 1 layerpanel_checkbox_hei = layerpanel_buttonheight-4;
21032 1 layerpanel_checkbox_wid = 15;
21033
21034 1 minimap.x=3;
21035 1 minimap.y=layer_panel.y+layer_panel.h+4;
21036
21037 1 real_minimap.x = minimap.x+3;
21038 1 real_minimap.y = minimap.y+5;
21039 1 real_minimap.w = 16;
21040 1 real_minimap.h = 9;
21041 1 real_minimap.xscale = 9;
21042 1 real_minimap.yscale = 9;
21043 1 real_minimap.fw = real_minimap.xscale*8;
21044 1 real_minimap.fh = real_minimap.yscale*8;
21045
21046 1 int upscale_mm = 3;
21047 1 int xwid = real_minimap.tw()*(upscale_mm-1);
21048 1 int xhei = real_minimap.th()*(upscale_mm-1);
21049 1 minimap_zoomed.set(minimap.x, minimap.y-xhei, minimap.w+xwid, minimap.h+xhei+4);
21050 1 real_minimap_zoomed.set(minimap_zoomed.x+3, minimap_zoomed.y+5, real_minimap.w, real_minimap.h, real_minimap.xscale*upscale_mm, real_minimap.yscale*upscale_mm);
21051 1 real_minimap_zoomed.fw = real_minimap_zoomed.xscale*8;
21052 1 real_minimap_zoomed.fh = real_minimap_zoomed.yscale*8;
21053
21054 1 screrrorpos.x = combolist_window.x - 3;
21055 1 screrrorpos.y = layer_panel.y - 16;
21056
21057 1 mouse_scroll_h=10;
21058
21059 1 favorites_list.x=favorites_window.x+8;
21060 1 favorites_list.y=favorites_window.y+16;
21061 1 favorites_list.xscale = 16;
21062 1 favorites_list.yscale = 16;
21063 1 favorites_list.w=(favorites_window.w-16)/favorites_list.xscale;
21064 1 favorites_list.h=(favorites_window.h-24)/favorites_list.yscale;
21065
21066 1 commands_list.w=4;
21067
21068 1 int bh = commands_list.yscale;
21069 1 int bw = 26;
21070 1 commands_window.w=commands_list.w*commands_list.xscale+10+bw;
21071 1 commands_window.x=combolist_window.x-commands_window.w;
21072 1 commands_window.y=layer_panel.y+layer_panel.h;
21073 1 commands_window.h=zq_screen_h-commands_window.y;
21074 1 int bx = commands_window.x+2;
21075
21076 1 commands_list.y=commands_window.y+4;
21077 1 commands_list.h=(zq_screen_h - commands_list.y) / commands_list.yscale;
21078 1 commands_list.x=bx+bw;
21079
21080 1 commands_zoombtn.w = bw;
21081 1 commands_zoombtn.h = bh;
21082 1 commands_zoombtn.x = bx;
21083 1 commands_zoombtn.y = commands_list.y;
21084
21085 1 commands_infobtn.w = bw;
21086 1 commands_infobtn.h = bh;
21087 1 commands_infobtn.x = bx;
21088 1 commands_infobtn.y = commands_zoombtn.y + commands_infobtn.h;
21089
21090 1 commands_x.w = bw;
21091 1 commands_x.h = bh;
21092 1 commands_x.x = bx;
21093 1 commands_x.y = commands_infobtn.y + commands_x.h;
21094
21095 1 commands_txt.clear();
21096
21097 1 main_panel.x = 0;
21098 1 main_panel.y = layer_panel.y+layer_panel.h;
21099 1 main_panel.w = commands_window.x - main_panel.x;
21100 1 main_panel.h = 76+32;
21101 1 preview_panel = main_panel;
21102 1 preview_panel.x = 0;
21103 1 preview_panel.w = commands_window.x - preview_panel.x;
21104
21105 1 preview_text.x = preview_panel.x+3;
21106 1 preview_text.y = preview_panel.y+3;
21107 1 preview_text.w = 2;
21108 1 preview_text.h = 6;
21109 1 preview_text.xscale = 10;
21110 1 preview_text.yscale = text_height(get_zc_font(font_lfont_l));
21111
21112 1 panel_align = 1;
21113 1 int swapbtnw = 32, swapbtnh = 20;
21114 1 int swapbtnx = main_panel.x+main_panel.tw()-swapbtnw;
21115 1 squarepanel_swap_btn.set(swapbtnx, zq_screen_h-swapbtnh, swapbtnw, swapbtnh);
21116
21117 1 int sqx = minimap.x+minimap.tw();
21118 1 squares_panel.set(sqx,main_panel.y,main_panel.tw()-sqx,main_panel.th());
21119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(compact_square_panels)
21120 {
21121 int cmpy = main_panel.y+(main_panel.th()/2);
21122 squarepanel_up_btn.set(swapbtnx, cmpy-swapbtnh, swapbtnw, swapbtnh);
21123 squarepanel_down_btn.set(swapbtnx, cmpy, swapbtnw, swapbtnh);
21124
21125 txtoffs_single.x = 18;
21126 txtoffs_single.y = 36;
21127 txtoffs_double_1.x = 18;
21128 txtoffs_double_1.y = 36;
21129 txtoffs_double_2.x = 18;
21130 txtoffs_double_2.y = 36 + text_height(get_custom_font(CFONT_GUI));
21131
21132 //Clear them all- if they stay cleared, they are invisible.
21133 itemsqr_pos.clear();
21134 stairsqr_pos.clear();
21135 warparrival_pos.clear();
21136 flagsqr_pos.clear();
21137 enemy_prev_pos.clear();
21138 for(int q = 0; q < 4; ++q)
21139 warpret_pos[q].clear();
21140
21141 int sqr_x1 = sqx+12;
21142 int sqr_y1 = main_panel.y+12;
21143 int sqr_xoffs = (16*2)+4 + 12;
21144 switch(compact_active_panel)
21145 {
21146 case 0: //Warp Squares
21147 {
21148 int x = sqr_x1;
21149 for(int q = 0; q < 4; ++q)
21150 {
21151 warpret_pos[q].set(x,sqr_y1,(16*2)+4,(16*2)+4);
21152 x += sqr_xoffs;
21153 }
21154 break;
21155 }
21156 case 1: //Other Squares
21157 {
21158 itemsqr_pos.set(sqr_x1+(sqr_xoffs*0), sqr_y1, (16*2)+4,(16*2)+4);
21159 stairsqr_pos.set(sqr_x1+(sqr_xoffs*1), sqr_y1, (16*2)+4,(16*2)+4);
21160 warparrival_pos.set(sqr_x1+(sqr_xoffs*2), sqr_y1, (16*2)+4,(16*2)+4);
21161 flagsqr_pos.set(sqr_x1+(sqr_xoffs*3), sqr_y1, (16*2)+4,(16*2)+4);
21162 break;
21163 }
21164 case 2: //Enemy Preview
21165 {
21166 enemy_prev_pos.set(sqr_x1, sqr_y1, 5, 2, 32, 32);
21167 break;
21168 }
21169 }
21170 }
21171 else
21172 {
21173 1 squarepanel_up_btn.clear();
21174 1 squarepanel_down_btn.clear();
21175 1 txtoffs_single.x = 10;
21176 1 txtoffs_single.y = 22;
21177 1 txtoffs_double_1.x = 10;
21178 1 txtoffs_double_1.y = 22;
21179 1 txtoffs_double_2.x = 10;
21180 1 txtoffs_double_2.y = 30;
21181
21182
21183 1 int sqr_x1 = sqx+24;
21184 1 int sqr_y1 = main_panel.y+12;
21185 1 int sqr_y2 = sqr_y1+42;
21186 1 int sqr_xdist = 32;
21187 1 itemsqr_pos.set(sqr_x1+(sqr_xdist*0),sqr_y1,20,20);
21188 1 stairsqr_pos.set(sqr_x1+(sqr_xdist*1),sqr_y1,20,20);
21189 1 warparrival_pos.set(sqr_x1+(sqr_xdist*2),sqr_y1,20,20);
21190 1 flagsqr_pos.set(sqr_x1+(sqr_xdist*3),sqr_y1,20,20);
21191
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 for(auto q = 0; q < 4; ++q)
21192 {
21193 4 warpret_pos[q].set(sqr_x1+(sqr_xdist*q),sqr_y2,20,20);
21194 4 }
21195 1 enemy_prev_pos.set(sqr_x1+(sqr_xdist*4), sqr_y1, 4, 3, 16, 16);
21196 1 enemy_prev_pos.fw = enemy_prev_pos.xscale*2;
21197 1 enemy_prev_pos.fh = enemy_prev_pos.yscale*2;
21198 }
21199
21200 1 auto& last_alias_list = comboaliaslist[num_combo_cols-1];
21201 1 combopool_preview.x=comboaliaslist[0].x;
21202 1 combopool_preview.y=last_alias_list.y+(last_alias_list.h*last_alias_list.yscale)+16;
21203 1 combopool_preview.w=(last_alias_list.x+(last_alias_list.w*last_alias_list.xscale))-comboaliaslist[0].x;
21204 1 combopool_preview.h=zq_screen_h-8-combopool_preview.y;
21205 1 combopool_preview.w -= combopool_preview.w%16;
21206 1 combopool_preview.h -= combopool_preview.h%16;
21207
21208 1 FONT* tfont = get_zc_font(font_lfont_l);
21209 1 combopool_prevbtn.w = text_length(tfont, "Unweighted")+10;
21210 1 combopool_prevbtn.h = 11;
21211 1 combopool_prevbtn.x = combopool_preview.x;
21212 1 combopool_prevbtn.y = combopool_preview.y-combopool_prevbtn.h;
21213
21214 1 mappage_count = 6;
21215
21216 1 txfont = get_zc_font(font_lfont_l);
21217 1 combo_preview_text1.set(combo_preview.x-5,combo_preview.y,1,3,1,text_height(txfont));
21218 1 combo_preview_text2.clear();
21219
21220 1 favorites_x.w = 17;
21221 1 favorites_infobtn.w = 17;
21222 1 favorites_zoombtn.w = 17;
21223 1 favorites_pgleft.w = 17;
21224 1 favorites_pgright.w = 17;
21225 1 }
21226 else
21227 {
21228 num_combo_cols = 4;
21229 combo_col_scale = 16;
21230 if(large_merged_combopane)
21231 {
21232 num_combo_cols = 2;
21233 combo_col_scale = 32;
21234 }
21235
21236 mapscreen_x=0;
21237 mapscreen_y=dialogs[0].h;
21238 mapscreen_screenunit_scale=2;
21239 mapscreen_single_scale = (double)mapscreen_screenunit_scale / Map.getViewSize();
21240 if (HighQualityScreenRendering)
21241 showedges=Map.getViewSize() == 1 ? 1 : 0;
21242 else
21243 showedges=Map.getViewSize() <= 2 ? 1 : 0;
21244 showallpanels=0;
21245
21246 blackout_color=8;
21247
21248 favorites_window.h=136;
21249 favorites_window.y=zq_screen_h-favorites_window.h;
21250
21251 auto mapscr_wid = (((2)+16)*16*mapscreen_screenunit_scale);
21252 combolist_window.w=zq_screen_w-mapscr_wid;
21253 combolist_window.x=zq_screen_w-combolist_window.w;
21254 combolist_window.y=0;
21255 combolist_window.h=favorites_window.y-combolist_window.y;
21256
21257 favorites_window.x=combolist_window.x;
21258 favorites_window.w=combolist_window.w;
21259
21260 combo_preview.x=(zq_screen_w-(combolist_window.w/2))-40;
21261 combo_preview.y=combolist_window.y+6;
21262 combo_preview.w=32;
21263 combo_preview.h=32;
21264 combo_preview2 = combo_preview;
21265 combo_preview2.x += 48;
21266
21267 auto col_wid = 4*combo_col_scale;
21268 auto cols_wid = col_wid * num_combo_cols;
21269 auto cols_spacing = (combolist_window.w-cols_wid)/(num_combo_cols+1);
21270 for(auto q = 0; q < num_combo_cols; ++q)
21271 {
21272 combolist[q].x=combolist_window.x+(cols_spacing*(q+1))+(col_wid*q);
21273 combolist[q].y=combolist_window.y+60;
21274 combolist[q].w=4;
21275 combolist[q].h=large_merged_combopane ? 15 : 30;
21276 combolist[q].xscale = combo_col_scale;
21277 combolist[q].yscale = combo_col_scale;
21278
21279 comboaliaslist[q].x=combolist[q].x;
21280 comboaliaslist[q].y=combolist[q].y;
21281 comboaliaslist[q].w=4;
21282 comboaliaslist[q].h=large_merged_combopane ? 12 : 25;
21283 comboaliaslist[q].xscale = combo_col_scale;
21284 comboaliaslist[q].yscale = combo_col_scale;
21285
21286 combolistscrollers[q].w=2;
21287 combolistscrollers[q].h=1;
21288 combolistscrollers[q].xscale=11;
21289 combolistscrollers[q].yscale=11;
21290 combolistscrollers[q].x=combolist[q].x+(combolist[q].w*combolist[q].xscale/2)-11;
21291 combolistscrollers[q].y=combolist[q].y-combolistscrollers[q].th()-2;
21292 }
21293
21294 comboalias_preview.x=zq_screen_w-((combolist_window.w+64)/2);
21295 comboalias_preview.h=64;
21296 comboalias_preview.w=64;
21297 comboalias_preview.y=favorites_window.y-comboalias_preview.h-8;
21298
21299 combo_merge_btn.w = 20;
21300 combo_merge_btn.h = 20;
21301 combo_merge_btn.x = zq_screen_w-(combolist_window.w+combo_merge_btn.w)/2;
21302 combo_merge_btn.y = combolist[0].y-combo_merge_btn.h;
21303 squarepanel_swap_btn.clear();
21304 squarepanel_up_btn.clear();
21305 squarepanel_down_btn.clear();
21306
21307 drawmode_btn.x = combolist_window.x-drawmode_wid;
21308 drawmode_btn.y = 0;
21309 drawmode_btn.w = drawmode_wid;
21310 drawmode_btn.h = mapscreen_y;
21311
21312 compactbtn.w = text_length(guifont,"> Compact")+10;
21313 compactbtn.x = drawmode_btn.x-compactbtn.w;
21314 compactbtn.y = drawmode_btn.y;
21315 compactbtn.h = drawmode_btn.h;
21316
21317 zoominbtn.w = text_length(guifont,"+")+10;
21318 zoominbtn.x = compactbtn.x-zoominbtn.w;
21319 zoominbtn.y = compactbtn.y;
21320 zoominbtn.h = compactbtn.h;
21321
21322 zoomoutbtn.w = text_length(guifont,"-")+10;
21323 zoomoutbtn.x = zoominbtn.x-zoomoutbtn.w;
21324 zoomoutbtn.y = compactbtn.y;
21325 zoomoutbtn.h = compactbtn.h;
21326
21327 for(int32_t i=0; i<=8; i++)
21328 {
21329 map_page_bar[i].x = mapscreen_x+(i*16*2*mapscreen_screenunit_scale);
21330 map_page_bar[i].y = mapscreen_y+((13)*16*mapscreen_screenunit_scale);
21331 map_page_bar[i].w = 64;
21332 map_page_bar[i].h = text_height(guifont)+12;
21333 }
21334
21335 minimap.w=7+48*3;
21336 minimap.h=16+27*3;
21337
21338 layer_panel.x=map_page_bar[0].x;
21339 layer_panel.y=map_page_bar[0].y+map_page_bar[0].h;
21340 layer_panel.w=map_page_bar[8].x+map_page_bar[8].w;
21341 layer_panel.h=text_height(guifont)+8;
21342 layerpanel_buttonwidth = 58;
21343 layerpanel_buttonheight = layer_panel.h;
21344 layerpanel_checkbox_hei = layerpanel_buttonheight-4;
21345 layerpanel_checkbox_wid = 14;
21346
21347 commands_list.w=4;
21348 commands_window.w=commands_list.w*commands_list.xscale+16;
21349 commands_window.x=combolist_window.x-commands_window.w;
21350 commands_window.y=layer_panel.y+layer_panel.h;
21351 commands_window.h=zq_screen_h-commands_window.y;
21352
21353 //buttons panel
21354 main_panel.x = 0;
21355 main_panel.y = layer_panel.y+layer_panel.h;
21356 main_panel.w = commands_window.x - main_panel.x;
21357 main_panel.h = zq_screen_h - main_panel.y;
21358 preview_panel = main_panel;
21359
21360 preview_text.x = preview_panel.x+3;
21361 preview_text.y = preview_panel.y+3;
21362 preview_text.w = 1;
21363 preview_text.h = 12;
21364 preview_text.xscale = 10;
21365 preview_text.yscale = text_height(get_zc_font(font_lfont_l));
21366
21367 minimap.x=3;
21368 minimap.y=main_panel.y+4;
21369
21370 real_minimap.x = minimap.x+3;
21371 real_minimap.y = minimap.y+5;
21372 real_minimap.w = 16;
21373 real_minimap.h = 9;
21374 real_minimap.xscale = 9;
21375 real_minimap.yscale = 9;
21376 real_minimap.fw = real_minimap.xscale*8;
21377 real_minimap.fh = real_minimap.yscale*8;
21378
21379 int upscale_mm = 4;
21380 int xwid = real_minimap.tw()*(upscale_mm-1);
21381 int xhei = real_minimap.th()*(upscale_mm-1);
21382 int zh = minimap.h+xhei+4;
21383 minimap_zoomed.set(minimap.x, zq_screen_h-zh, minimap.w+xwid, zh);
21384 real_minimap_zoomed.set(minimap_zoomed.x+3, minimap_zoomed.y+5, real_minimap.w, real_minimap.h, real_minimap.xscale*upscale_mm, real_minimap.yscale*upscale_mm);
21385 real_minimap_zoomed.fw = real_minimap_zoomed.xscale*8;
21386 real_minimap_zoomed.fh = real_minimap_zoomed.yscale*8;
21387
21388 screrrorpos.x = 575;
21389 screrrorpos.y = 388;
21390
21391 mouse_scroll_h=10;
21392
21393 favorites_list.x=favorites_window.x+8;
21394 favorites_list.y=favorites_window.y+16;
21395 favorites_list.xscale = 16;
21396 favorites_list.yscale = 16;
21397 favorites_list.w=(favorites_window.w-16)/favorites_list.xscale;
21398 favorites_list.h=(favorites_window.h-24)/favorites_list.yscale;
21399
21400 int bh = 16;
21401 int by = commands_window.y+4;
21402 commands_list.y=by+bh;
21403 commands_list.h=(zq_screen_h - commands_list.y) / commands_list.yscale;
21404 commands_list.x=commands_window.x+8;
21405
21406 commands_x.w = 20;
21407 commands_x.h = bh;
21408 commands_x.x = commands_list.x + commands_list.tw() - commands_x.w;
21409 commands_x.y = by;
21410
21411 commands_infobtn.w = 20;
21412 commands_infobtn.h = bh;
21413 commands_infobtn.x = commands_x.x - commands_infobtn.w;
21414 commands_infobtn.y = by;
21415
21416 commands_zoombtn.w = 20;
21417 commands_zoombtn.h = bh;
21418 commands_zoombtn.x = commands_infobtn.x - commands_zoombtn.w;
21419 commands_zoombtn.y = by;
21420
21421 commands_txt.x = commands_list.x;
21422 commands_txt.y = by+(bh-text_height(get_zc_font(font_lfont_l)))/2;
21423
21424 favorites_x.x = favorites_window.x + favorites_window.w - favorites_x.w - 2;
21425 favorites_x.y = favorites_list.y-15;
21426
21427 favorites_infobtn.x = favorites_x.x - favorites_infobtn.w;
21428 favorites_infobtn.y = favorites_x.y;
21429
21430 favorites_zoombtn.x = favorites_infobtn.x - favorites_zoombtn.w;
21431 favorites_zoombtn.y = favorites_infobtn.y;
21432
21433 favorites_pgright.x = favorites_zoombtn.x - favorites_pgright.w;
21434 favorites_pgright.y = favorites_zoombtn.y;
21435
21436 favorites_pgleft.x = favorites_pgright.x - favorites_pgleft.w;
21437 favorites_pgleft.y = favorites_pgleft.y;
21438
21439 txtoffs_single.x = 22;
21440 txtoffs_single.y = 6;
21441 txtoffs_double_1.x = 22;
21442 txtoffs_double_1.y = 2;
21443 txtoffs_double_2.x = 22;
21444 txtoffs_double_2.y = 10;
21445 panel_align = 0;
21446
21447 int sqx = minimap.x+minimap.tw();
21448 squares_panel.set(sqx,main_panel.y,main_panel.tw()-sqx,main_panel.th());
21449 int x2 = sqx+4;
21450 int x1 = x2 - (20+(8*3)+2);
21451 int y1 = main_panel.y+10;
21452 int sw = 20, sh = 20;
21453 int offs = sh+4;
21454
21455 itemsqr_pos.set(x2,y1+(0*offs),sw,sh);
21456 flagsqr_pos.set(x2,y1+(1*offs),sw,sh);
21457 stairsqr_pos.set(x2,y1+(2*offs),sw,sh);
21458 warparrival_pos.set(x2,y1+(6*offs),sw,sh);
21459
21460 enemy_prev_pos.x = main_panel.x+14;
21461 enemy_prev_pos.y = main_panel.y+12 + minimap.h;
21462 enemy_prev_pos.w = 4;
21463 enemy_prev_pos.h = 3;
21464 enemy_prev_pos.xscale = 16;
21465 enemy_prev_pos.yscale = 16;
21466 enemy_prev_pos.fw = enemy_prev_pos.xscale*2;
21467 enemy_prev_pos.fh = enemy_prev_pos.yscale*2;
21468
21469 warpret_pos[0].set(x1,y1+(4*offs),sw,sh);
21470 warpret_pos[1].set(x1,y1+(5*offs),sw,sh);
21471 warpret_pos[2].set(x2,y1+(4*offs),sw,sh);
21472 warpret_pos[3].set(x2,y1+(5*offs),sw,sh);
21473
21474 auto& last_alias_list = comboaliaslist[num_combo_cols-1];
21475 combopool_preview.x=comboaliaslist[0].x;
21476 combopool_preview.y=last_alias_list.y+(last_alias_list.h*last_alias_list.yscale)+16;
21477 combopool_preview.w=(last_alias_list.x+(last_alias_list.w*last_alias_list.xscale))-comboaliaslist[0].x;
21478 combopool_preview.h=(favorites_window.y-combopool_preview.y);//+favorites_window.h-10;
21479 combopool_preview.w -= combopool_preview.w%16;
21480 combopool_preview.h -= combopool_preview.h%16;
21481
21482 FONT* tfont = get_zc_font(font_lfont_l);
21483 combopool_prevbtn.w = text_length(tfont, "Unweighted")+10;
21484 combopool_prevbtn.h = 11;
21485 combopool_prevbtn.x = combopool_preview.x;
21486 combopool_prevbtn.y = combopool_preview.y-combopool_prevbtn.h;
21487
21488 mappage_count = 9;
21489
21490 txfont = get_zc_font(font_lfont_l);
21491 combo_preview_text1.set(combo_preview.x-9,combo_preview.y,1,3,1,text_height(txfont));
21492 combo_preview_text2.set(combo_preview2.x+combo_preview2.w+8,combo_preview2.y,1,3,1,text_height(txfont));
21493
21494 favorites_x.w = 30;
21495 favorites_infobtn.w = 30;
21496 favorites_zoombtn.w = 30;
21497 favorites_pgleft.w = 30;
21498 favorites_pgright.w = 30;
21499 }
21500 //Same in all modes
21501 {
21502
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(is_compact ? compact_zoomed_cmd : large_zoomed_cmd)
21503 {
21504 1 commands_list.w /= 2;
21505 1 commands_list.xscale *= 2;
21506 1 }
21507
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(is_compact ? compact_zoomed_fav : large_zoomed_fav)
21508 {
21509
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(favorites_list.w%2)
21510 favorites_list.x += (favorites_list.xscale / 2);
21511 1 favorites_list.xscale *= 2;
21512 1 favorites_list.yscale *= 2;
21513 1 favorites_list.w /= 2;
21514 1 favorites_list.h /= 2;
21515 1 }
21516
21517 1 favorites_x.h = 14;
21518 1 favorites_x.x = favorites_window.x + favorites_window.w - favorites_x.w - 2;
21519 1 favorites_x.y = favorites_list.y-15;
21520
21521 1 favorites_infobtn.h = favorites_x.h;
21522 1 favorites_infobtn.x = favorites_x.x - favorites_infobtn.w;
21523 1 favorites_infobtn.y = favorites_x.y;
21524
21525 1 favorites_zoombtn.h = favorites_infobtn.h;
21526 1 favorites_zoombtn.x = favorites_infobtn.x - favorites_zoombtn.w;
21527 1 favorites_zoombtn.y = favorites_infobtn.y;
21528
21529 1 favorites_pgright.h = favorites_zoombtn.h;
21530 1 favorites_pgright.x = favorites_zoombtn.x - favorites_pgright.w;
21531 1 favorites_pgright.y = favorites_zoombtn.y;
21532
21533 1 favorites_pgleft.h = favorites_pgright.h;
21534 1 favorites_pgleft.x = favorites_pgright.x - favorites_pgleft.w;
21535 1 favorites_pgleft.y = favorites_pgright.y;
21536
21537 1 mainbar.x = dialogs[0].x+dialogs[0].w;
21538 1 mainbar.y = 0;
21539 1 mainbar.w = zoomoutbtn.x-mainbar.x;
21540 1 mainbar.h = drawmode_btn.h;
21541 }
21542
21543 //Ensure current combo list selected is valid
21544 1 current_combolist=vbound(current_combolist,0,num_combo_cols-1);
21545 1 current_comboalist=vbound(current_comboalist,0,num_combo_cols-1);
21546 1 current_cpoollist=vbound(current_cpoollist,0,num_combo_cols-1);
21547 1 current_cautolist = vbound(current_cautolist, 0, num_combo_cols - 1);
21548
21549 //Generate bitmaps
21550 1 init_bitmap(&mapscreenbmp,16*(showedges?18:16),16*(showedges?13:11));
21551 1 init_bitmap(&brushbmp,256*mapscreen_screenunit_scale,176*mapscreen_screenunit_scale);
21552 1 init_bitmap(&brushscreen,(256+(showedges?16:0))*mapscreen_screenunit_scale,(176+(showedges?16:0))*mapscreen_screenunit_scale);
21553
21554 1 init_bitmap(&screen2,zq_screen_w,zq_screen_h);
21555
21556 1 center_zq_class_dialogs();
21557 1 center_zq_files_dialogs();
21558 1 center_zq_subscreen_dialogs();
21559 1 center_zq_tiles_dialogs();
21560 1 center_zquest_dialogs();
21561
21562 1 aspect_ratio = zq_screen_h / double(zq_screen_w);
21563
21564 1 mmap_init();
21565 1 }
21566
21567 11 void remove_locked_params_on_exit()
21568 {
21569 11 al_trace("Removing timers. \n");
21570 11 remove_int(fps_callback);
21571 11 remove_int(dclick_check);
21572 11 }
21573
21574 11 void destroy_bitmaps_on_exit()
21575 {
21576 11 al_trace("Cleaning bitmaps...");
21577 11 destroy_bitmap(screen2);
21578 11 destroy_bitmap(mapscreenbmp);
21579 11 destroy_bitmap(dmapbmp_small);
21580 11 destroy_bitmap(dmapbmp_large);
21581 11 destroy_bitmap(brushbmp);
21582 11 destroy_bitmap(brushscreen);
21583 11 al_trace("...");
21584
21585
2/2
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 11 times.
539 for(int32_t i=0; i<MOUSE_BMP_MAX*4; i++)
21586 {
21587 528 destroy_bitmap(mouse_bmp[i/4][i%4]);
21588 528 destroy_bitmap(mouse_bmp_1x[i/4][i%4]);
21589 528 }
21590
21591
2/2
✓ Branch 0 taken 352 times.
✓ Branch 1 taken 11 times.
363 for(int32_t i=0; i<ICON_BMP_MAX*4; i++)
21592 352 destroy_bitmap(icon_bmp[i/4][i%4]);
21593
21594
2/2
✓ Branch 0 taken 704 times.
✓ Branch 1 taken 11 times.
715 for(int32_t i=0; i<16*4; i++)
21595 704 destroy_bitmap(flag_bmp[i/4][i%4]);
21596
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 11 times.
33 for(int32_t i=0; i<2; i++)
21597 22 destroy_bitmap(select_bmp[i]);
21598
21599
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 11 times.
99 for(int32_t i=0; i<MAXARROWS; i++)
21600 88 destroy_bitmap(arrow_bmp[i]);
21601
21602 11 al_trace(" OK. \n");
21603 11 }
21604
21605
21606 11 void quit_game()
21607 {
21608 11 set_last_timed_save(nullptr);
21609 11 save_config_file();
21610 11 zc_set_palette(black_palette);
21611 11 zc_stop_midi();
21612
21613 11 remove_locked_params_on_exit();
21614
21615 11 al_trace("Cleaning sfx. \n");
21616
21617
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<WAV_COUNT; i++)
21618 {
21619
2/2
✓ Branch 0 taken 2805 times.
✓ Branch 1 taken 11 times.
2816 if(customsfxdata[i].data!=NULL)
21620 {
21621 // delete [] customsfxdata[i].data;
21622 2805 free(customsfxdata[i].data);
21623 2805 }
21624
21625
1/2
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
2816 delete [] sfx_string[i];
21626 2816 }
21627
21628
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<MAXWPNS; i++)
21629 {
21630
1/2
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
2816 delete [] weapon_string[i];
21631 2816 }
21632
21633
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<MAXITEMS; i++)
21634 {
21635
1/2
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
2816 delete [] item_string[i];
21636 2816 }
21637
21638
2/2
✓ Branch 0 taken 5632 times.
✓ Branch 1 taken 11 times.
5643 for(int32_t i=0; i<eMAXGUYS; i++)
21639 {
21640
1/2
✓ Branch 0 taken 5632 times.
✗ Branch 1 not taken.
5632 delete [] guy_string[i];
21641 5632 }
21642
21643 11 al_trace("Cleaning script buffer. \n");
21644
21645
2/2
✓ Branch 0 taken 5632 times.
✓ Branch 1 taken 11 times.
5643 for(int32_t i=0; i<NUMSCRIPTFFC; i++)
21646 {
21647
2/4
✓ Branch 0 taken 5632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5632 times.
5632 if(ffscripts[i]!=NULL) delete ffscripts[i];
21648 5632 }
21649
21650
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTITEM; i++)
21651 {
21652
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(itemscripts[i]!=NULL) delete itemscripts[i];
21653 2816 }
21654
21655
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTGUYS; i++)
21656 {
21657
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(guyscripts[i]!=NULL) delete guyscripts[i];
21658 2816 }
21659
21660
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
21661 {
21662
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(lwpnscripts[i]!=NULL) delete lwpnscripts[i];
21663 2816 }
21664
21665
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
21666 {
21667
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(ewpnscripts[i]!=NULL) delete ewpnscripts[i];
21668 2816 }
21669
21670
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTSCREEN; i++)
21671 {
21672
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(screenscripts[i]!=NULL) delete screenscripts[i];
21673 2816 }
21674
21675
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 11 times.
44 for(int32_t i=0; i<3; i++) //should this be NUMSCRIPTGLOBAL or NUMSCRIPTGLOBALOLD? -Z
21676 {
21677
2/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
33 if(globalscripts[i]!=NULL) delete globalscripts[i];
21678 33 }
21679
21680
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 11 times.
66 for(int32_t i=0; i<NUMSCRIPTHERO; i++)
21681 {
21682
2/4
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55 times.
55 if(playerscripts[i]!=NULL) delete playerscripts[i];
21683 55 }
21684
21685
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTSDMAP; i++)
21686 {
21687
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(dmapscripts[i]!=NULL) delete dmapscripts[i];
21688 2816 }
21689
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTSITEMSPRITE; i++)
21690 {
21691
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(itemspritescripts[i]!=NULL) delete itemspritescripts[i];
21692 2816 }
21693
2/2
✓ Branch 0 taken 5632 times.
✓ Branch 1 taken 11 times.
5643 for(int32_t i=0; i<NUMSCRIPTSCOMBODATA; i++)
21694 {
21695
2/4
✓ Branch 0 taken 5632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5632 times.
5632 if(comboscripts[i]!=NULL) delete comboscripts[i];
21696 5632 }
21697
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2816 times.
2827 for(int32_t i=0; i<NUMSCRIPTSSUBSCREEN; i++)
21698 {
21699
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(subscreenscripts[i]!=NULL) delete subscreenscripts[i];
21700 2816 }
21701
21702 11 al_trace("Cleaning qst buffers. \n");
21703 11 del_qst_buffers();
21704
21705
21706 11 al_trace("Cleaning midis. \n");
21707
21708
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(customtunes)
21709 {
21710
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<MAXCUSTOMMIDIS_ZQ; i++)
21711 2816 customtunes[i].reset();
21712
21713 11 free(customtunes);
21714 11 }
21715
21716 11 al_trace("Cleaning undotilebuf. \n");
21717
21718 11 undocombobuf.clear();
21719
21720
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(newundotilebuf)
21721 {
21722
2/2
✓ Branch 0 taken 2359500 times.
✓ Branch 1 taken 11 times.
2359511 for(int32_t i=0; i<NEWMAXTILES; i++)
21723
1/2
✓ Branch 0 taken 2359500 times.
✗ Branch 1 not taken.
2359500 if(newundotilebuf[i].data) free(newundotilebuf[i].data);
21724
21725 11 free(newundotilebuf);
21726 11 }
21727
21728
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(filepath) free(filepath);
21729
21730
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(datapath) free(datapath);
21731
21732
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(midipath) free(midipath);
21733
21734
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(imagepath) free(imagepath);
21735
21736
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(tmusicpath) free(tmusicpath);
21737
21738
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(last_timed_save) free(last_timed_save);
21739
21740 11 destroy_bitmaps_on_exit();
21741 11 }
21742
21743 void quit_game2()
21744 {
21745 set_last_timed_save(nullptr);
21746 save_config_file();
21747 zc_set_palette(black_palette);
21748 zc_stop_midi();
21749
21750 remove_locked_params_on_exit();
21751
21752 al_trace("Cleaning sfx. \n");
21753
21754 for(int32_t i=0; i<WAV_COUNT; i++)
21755 {
21756 if(customsfxdata[i].data!=NULL)
21757 {
21758 // delete [] customsfxdata[i].data;
21759 free(customsfxdata[i].data);
21760 }
21761
21762 delete [] sfx_string[i];
21763 }
21764
21765 for(int32_t i=0; i<MAXWPNS; i++)
21766 {
21767 delete [] weapon_string[i];
21768 }
21769
21770 for(int32_t i=0; i<MAXITEMS; i++)
21771 {
21772 delete [] item_string[i];
21773 }
21774
21775 for(int32_t i=0; i<eMAXGUYS; i++)
21776 {
21777 delete [] guy_string[i];
21778 }
21779
21780 al_trace("Cleaning script buffer. \n");
21781
21782 for(int32_t i=0; i<NUMSCRIPTFFC; i++)
21783 {
21784 if(ffscripts[i]!=NULL) delete ffscripts[i];
21785 }
21786
21787 for(int32_t i=0; i<NUMSCRIPTITEM; i++)
21788 {
21789 if(itemscripts[i]!=NULL) delete itemscripts[i];
21790 }
21791
21792 for(int32_t i=0; i<NUMSCRIPTGUYS; i++)
21793 {
21794 if(guyscripts[i]!=NULL) delete guyscripts[i];
21795 }
21796
21797 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
21798 {
21799 if(lwpnscripts[i]!=NULL) delete lwpnscripts[i];
21800 }
21801
21802 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
21803 {
21804 if(ewpnscripts[i]!=NULL) delete ewpnscripts[i];
21805 }
21806
21807 for(int32_t i=0; i<NUMSCRIPTSCREEN; i++)
21808 {
21809 if(screenscripts[i]!=NULL) delete screenscripts[i];
21810 }
21811
21812 for(int32_t i=0; i<3; i++) //should this be NUMSCRIPTGLOBAL or NUMSCRIPTGLOBALOLD? -Z
21813 {
21814 if(globalscripts[i]!=NULL) delete globalscripts[i];
21815 }
21816
21817 for(int32_t i=0; i<NUMSCRIPTHERO; i++)
21818 {
21819 if(playerscripts[i]!=NULL) delete playerscripts[i];
21820 }
21821
21822 for(int32_t i=0; i<NUMSCRIPTSDMAP; i++)
21823 {
21824 if(dmapscripts[i]!=NULL) delete dmapscripts[i];
21825 }
21826 for(int32_t i=0; i<NUMSCRIPTSITEMSPRITE; i++)
21827 {
21828 if(itemspritescripts[i]!=NULL) delete itemspritescripts[i];
21829 }
21830 for(int32_t i=0; i<NUMSCRIPTSCOMBODATA; i++)
21831 {
21832 if(comboscripts[i]!=NULL) delete comboscripts[i];
21833 }
21834 for(int32_t i=0; i<NUMSCRIPTSSUBSCREEN; i++)
21835 {
21836 if(subscreenscripts[i]!=NULL) delete subscreenscripts[i];
21837 }
21838
21839 al_trace("Cleaning qst buffers. \n");
21840 del_qst_buffers();
21841
21842
21843 al_trace("Cleaning midis. \n");
21844
21845 if(customtunes)
21846 {
21847 for(int32_t i=0; i<MAXCUSTOMMIDIS_ZQ; i++)
21848 customtunes[i].reset();
21849
21850 free(customtunes);
21851 }
21852
21853 al_trace("Cleaning undotilebuf. \n");
21854
21855 undocombobuf.clear();
21856
21857 if(newundotilebuf)
21858 {
21859 for(int32_t i=0; i<NEWMAXTILES; i++)
21860 if(newundotilebuf[i].data) free(newundotilebuf[i].data);
21861
21862 free(newundotilebuf);
21863 }
21864
21865 if(filepath) free(filepath);
21866
21867 if(datapath) free(datapath);
21868
21869 if(midipath) free(midipath);
21870
21871 if(imagepath) free(imagepath);
21872
21873 if(tmusicpath) free(tmusicpath);
21874
21875 if(last_timed_save) free(last_timed_save);
21876 }
21877
21878 1 void center_zquest_dialogs()
21879 {
21880 1 jwin_center_dialog(assignscript_dlg);
21881 1 center_zq_cset_dialogs();
21882 1 jwin_center_dialog(change_track_dlg);
21883 1 jwin_center_dialog(csetfix_dlg);
21884 1 center_zq_door_dialogs();
21885 1 jwin_center_dialog(editcomboa_dlg);
21886 1 jwin_center_dialog(editinfo_dlg);
21887 1 jwin_center_dialog(editshop_dlg);
21888 1 jwin_center_dialog(list_dlg);
21889 1 jwin_center_dialog(loadmap_dlg);
21890 1 jwin_center_dialog(misccolors_dlg);
21891 1 jwin_center_dialog(newcomboa_dlg);
21892 1 jwin_center_dialog(orgcomboa_dlg);
21893 1 jwin_center_dialog(path_dlg);
21894 1 jwin_center_dialog(screen_pal_dlg);
21895 1 jwin_center_dialog(secret_dlg);
21896 1 jwin_center_dialog(showpal_dlg);
21897 1 jwin_center_dialog(strlist_dlg);
21898 1 jwin_center_dialog(template_dlg);
21899 1 jwin_center_dialog(tp_dlg);
21900 1 jwin_center_dialog(tilewarp_dlg);
21901 1 jwin_center_dialog(sidewarp_dlg);
21902 1 jwin_center_dialog(warpring_dlg);
21903 1 center_zscript_dialogs();
21904 1 }
21905
21906
21907 void animate_coords()
21908 {
21909 coord_frame=(coord_timer>>3)&3;
21910
21911 if(++coord_timer>=(1<<5))
21912 {
21913 coord_timer=0;
21914 }
21915 }
21916
21917 static const char *help_list[] =
21918 {
21919 "PREVIEW MODE",
21920 "PgUp/PgDn - Scroll through hotkey list",
21921 "Esc/Enter - Exit Preview Mode",
21922 "R - Restore screen to original state",
21923 "C - Toggle combo cycling On/Off",
21924 "S - Trigger screen secrets",
21925 "Q/W/F - These still work",
21926 "P - Pause everything",
21927 "A - Advance frame-by-frame",
21928 "1-4 - Trigger tile warp A-D",
21929 "5-8 - Trigger side warp A-D",
21930 "9 - Enable timed warps",
21931 "",
21932 "",
21933 };
21934
21935 void do_previewtext()
21936 {
21937 FONT* oldfont = font;
21938 font = get_zc_font(font_lfont_l);
21939
21940 //Put in help areas
21941 auto& sqr = preview_text;
21942 int ind = 0, len = 0;
21943 for(int q = 0; q < 12; ++q)
21944 {
21945 int l = text_length(font, help_list[q]);
21946 if(len < l) len = l;
21947 }
21948 sqr.xscale = len+2;
21949 sqr.yscale = text_height(font);
21950 for(int col = 0; col < sqr.w; ++col)
21951 {
21952 for(int row = 0; row < sqr.h; ++row)
21953 {
21954 auto& line = sqr.subsquare(col,row);
21955 textprintf_ex(screen,font,line.x,line.y,jwin_pal[jcTEXTFG],-1,"%s",help_list[ind++]);
21956 }
21957 }
21958
21959 font = oldfont;
21960 }
21961
21962
21963 bool reload_fonts = false;
21964 void run_zq_frame()
21965 {
21966 if(reload_fonts)
21967 {
21968 init_custom_fonts();
21969 load_size_poses();
21970 reload_fonts = false;
21971 }
21972
21973 handlePreviewMode();
21974 domouse();
21975 get_screen_rti()->freeze = false;
21976 custom_vsync();
21977 refresh(rCLEAR|rALL);
21978 }
21979 1 int32_t d_nbmenu_proc(int32_t msg,DIALOG *d,int32_t c)
21980 {
21981
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 switch(msg)
21982 {
21983 case MSG_VSYNC:
21984 run_zq_frame();
21985 break;
21986 case MSG_GOTMOUSE:
21987 case MSG_XCHAR:
21988 ComboBrushPause=1;
21989 refresh(rMAP);
21990 ComboBrushPause=0;
21991 clear_tooltip();
21992 break;
21993 }
21994
21995 1 return GuiMenu::proc(msg,d,c);
21996 }
21997
21998 bool prv_press=false;
21999
22000 void dopreview()
22001 {
22002 refresh(rMAP);
22003
22004 while(!(gui_mouse_b()))
22005 {
22006 if(keypressed())
22007 {
22008 if(!prv_press)
22009 {
22010 prv_press=true;
22011
22012 switch(readkey()>>8)
22013 {
22014 case KEY_ESC:
22015 case KEY_ENTER:
22016 case KEY_ENTER_PAD:
22017 goto finished;
22018 break;
22019
22020 case KEY_F:
22021 Flags^=cFLAGS;
22022 refresh(rMAP);
22023 break;
22024
22025 case KEY_R:
22026 onReloadPreview();
22027 break;
22028
22029 case KEY_S:
22030 onSecretsPreview();
22031 break;
22032
22033 case KEY_C:
22034 onCopy();
22035 break;
22036
22037 case KEY_A:
22038 onAKey();
22039 break;
22040
22041 case KEY_P:
22042 onP();
22043 break;
22044
22045 case KEY_L:
22046 onShowDarkness();
22047 break;
22048
22049 case KEY_1:
22050 Map.prv_dowarp(0,0);
22051 prv_warp=0;
22052 break;
22053
22054 case KEY_2:
22055 Map.prv_dowarp(0,1);
22056 prv_warp=0;
22057 break;
22058
22059 case KEY_3:
22060 Map.prv_dowarp(0,2);
22061 prv_warp=0;
22062 break;
22063
22064 case KEY_4:
22065 Map.prv_dowarp(0,3);
22066 prv_warp=0;
22067 break;
22068
22069 case KEY_5:
22070 Map.prv_dowarp(1,0);
22071 prv_warp=0;
22072 break;
22073
22074 case KEY_6:
22075 Map.prv_dowarp(1,1);
22076 prv_warp=0;
22077 break;
22078
22079 case KEY_7:
22080 Map.prv_dowarp(1,2);
22081 prv_warp=0;
22082 break;
22083
22084 case KEY_8:
22085 Map.prv_dowarp(1,3);
22086 prv_warp=0;
22087 break;
22088
22089 case KEY_9:
22090 if(prv_twon)
22091 {
22092 prv_twon=0;
22093 Map.set_prvtime(0);
22094 prv_warp=0;
22095 }
22096 else
22097 {
22098 Map.set_prvtime(Map.get_prvscr()->timedwarptics);
22099 prv_twon=1;
22100 }
22101
22102 break;
22103
22104 case KEY_W:
22105 onShowWalkability();
22106 break;
22107
22108 case KEY_Q:
22109 onShowComboInfoCSet();
22110 break;
22111 }
22112 }
22113 else
22114 {
22115 readkey();
22116 }
22117 }
22118 else
22119 {
22120 prv_press=false;
22121 }
22122
22123 if(prv_warp)
22124 {
22125 Map.prv_dowarp(1,0);
22126 prv_warp=0;
22127 }
22128
22129 if(Map.get_prvfreeze())
22130 {
22131 if(Map.get_prvadvance())
22132 {
22133 custom_vsync();
22134 Map.set_prvadvance(0);
22135 }
22136 }
22137 else
22138 {
22139 custom_vsync();
22140 Map.set_prvadvance(0);
22141 }
22142
22143 refresh(rALL);
22144 }
22145
22146 finished:
22147 //Flags=of;
22148 reset_combo_animations();
22149 reset_combo_animations2();
22150 MouseSprite::set(ZQM_NORMAL);
22151 prv_mode=0;
22152 prv_warp=0;
22153 Map.end_prv();
22154 Map.refresh_color();
22155 refresh(rMAP+rMENU);
22156
22157 while(gui_mouse_b())
22158 {
22159 /* do nothing */
22160 rest(1);
22161 }
22162 }
22163
22164 void call_vidmode_dlg();
22165 int32_t onZQVidMode()
22166 {
22167 call_vidmode_dlg();
22168 return D_O_K;
22169 }
22170
22171 bool screenIsScrolling()
22172 {
22173 return false;
22174 }
22175
22176 void write_includepaths()
22177 {
22178 FILE* f = fopen("includepaths.txt", "w");
22179 if(f)
22180 {
22181 fwrite(FFCore.includePathString,1,strlen(FFCore.includePathString),f);
22182 fclose(f);
22183 }
22184 }
22185
22186 11 int32_t save_config_file()
22187 {
22188
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (!application_has_loaded) return 0;
22189
22190 char qtnametitle[20];
22191 char qtpathtitle[20];
22192 char *datapath2=(char *)malloc(2048);
22193 char *midipath2=(char *)malloc(2048);
22194 char *imagepath2=(char *)malloc(2048);
22195 char *tmusicpath2=(char *)malloc(2048);
22196 strcpy(datapath2, datapath);
22197 strcpy(midipath2, midipath);
22198 strcpy(imagepath2, imagepath);
22199 strcpy(tmusicpath2, tmusicpath);
22200 chop_path(datapath2);
22201 chop_path(midipath2);
22202 chop_path(imagepath2);
22203 chop_path(tmusicpath2);
22204 write_includepaths();
22205
22206 zc_set_config("zquest",data_path_name,datapath2);
22207 zc_set_config("zquest",midi_path_name,midipath2);
22208 zc_set_config("zquest",image_path_name,imagepath2);
22209 zc_set_config("zquest",tmusic_path_name,tmusicpath2);
22210
22211 if (all_get_display() && !all_get_fullscreen_flag() && SaveDragResize)
22212 {
22213 window_width = al_get_display_width(all_get_display());
22214 window_height = al_get_display_height(all_get_display());
22215 zc_set_config("zquest","window_width",window_width);
22216 zc_set_config("zquest","window_height",window_height);
22217 }
22218 if (all_get_display() && !all_get_fullscreen_flag() && SaveWinPos)
22219 {
22220 int o_window_x, o_window_y;
22221 al_get_window_position(all_get_display(), &o_window_x, &o_window_y);
22222 zc_set_config("zquest", "window_x", o_window_x);
22223 zc_set_config("zquest", "window_y", o_window_y);
22224 }
22225
22226 byte b = 0;
22227 for(int32_t x=0; x<7; x++)
22228 {
22229 set_bit(&b,x,LayerMaskInt[x]);
22230 }
22231
22232 zc_set_config("zquest","layer_mask",b);
22233
22234 flush_config_file();
22235 #ifdef __EMSCRIPTEN__
22236 em_sync_fs();
22237 #endif
22238 free(datapath2);
22239 free(midipath2);
22240 free(imagepath2);
22241 free(tmusicpath2);
22242 return 0;
22243 11 }
22244
22245 int32_t d_timer_proc(int32_t msg, DIALOG *d, int32_t c)
22246 {
22247 //these are here to bypass compiler warnings about unused arguments
22248 c=c;
22249 d=d;
22250
22251 switch(msg)
22252 {
22253 case MSG_IDLE:
22254 #ifdef _WIN32
22255 if(zqUseWin32Proc != FALSE)
22256 win32data.Update(Frameskip); //experimental win32 fixes
22257
22258 #endif
22259
22260 // This has been crashing on Windows, and it saves plenty without it
22261 //check_autosave();
22262 break;
22263 }
22264
22265 return D_O_K;
22266 }
22267
22268 void check_autosave()
22269 {
22270 if (!first_save)
22271 return;
22272
22273 if(AutoSaveInterval>0)
22274 {
22275 time(&auto_save_time_current);
22276 auto_save_time_diff = difftime(auto_save_time_current,auto_save_time_start);
22277
22278 if(auto_save_time_diff>AutoSaveInterval*60)
22279 {
22280 if (!autosaved)
22281 {
22282 MouseSprite::set(ZQM_NORMAL);
22283 replace_extension(last_timed_save, filepath, "qt0", 2047);
22284 set_last_timed_save(last_timed_save);
22285
22286 if((header.zelda_version != ZELDA_VERSION || header.build != VERSION_BUILD))
22287 {
22288 displayinfo("Auto Save","This quest was saved in an older version of ZQuest.\nIf you wish to use the autosave feature, you must manually save the files in this version first.");
22289 time(&auto_save_time_start);
22290 return;
22291 }
22292
22293 int32_t ret = save_quest(last_timed_save, true);
22294
22295 if(ret)
22296 {
22297 displayinfo("Error","Timed save did not complete successfully.");
22298 set_last_timed_save(nullptr);
22299 }
22300 else autosaved = true;
22301
22302 save_config_file();
22303 }
22304 time(&auto_save_time_start);
22305 }
22306 }
22307 }
22308
22309 void flushItemCache(bool) {}
22310 void ringcolor(bool forceDefault)
22311 {
22312 forceDefault=forceDefault;
22313 }
22314
22315 bool item_disabled(int32_t)
22316 {
22317 return false;
22318 }
22319
22320 int32_t onCmdExit()
22321 {
22322 // replaces onExit for the -large button command "Exit"
22323 close_button_quit = true;
22324 return 0;
22325 }
22326
22327 int32_t onQuickCompile()
22328 {
22329 if(do_compile_and_slots(1,false))
22330 {
22331 mark_save_dirty();
22332 InfoDialog("Quick Compile","Success!").show();
22333 }
22334 else
22335 {
22336 InfoDialog("Quick Compile","Failure!").show();
22337 }
22338 return 0;
22339 }
22340 int32_t onSmartCompile()
22341 {
22342 if(do_compile_and_slots(2,false))
22343 {
22344 mark_save_dirty();
22345 InfoDialog("Smart Compile","Success!").show();
22346 }
22347 else
22348 {
22349 InfoDialog("Smart Compile","Failure!").show();
22350 }
22351 return 0;
22352 }
22353
22354 int32_t strchrnum(char const* str, char c)
22355 {
22356 for(int32_t i=0; str[i]; ++i)
22357 {
22358 if(str[i]==c)
22359 {
22360 return i;
22361 }
22362 }
22363
22364 return -1;
22365 }
22366
22367 int32_t get_longest_line_length(FONT *f, char* str)
22368 {
22369 int32_t maxlen=0;
22370 char* tmpstr = str;
22371 char temp=0;
22372 int32_t t=0;
22373 int32_t new_t=-1;
22374 while(tmpstr[0])
22375 {
22376 t=strchrnum(tmpstr, '\n');
22377
22378 if(t==-1)
22379 {
22380 t=(int32_t)strlen(tmpstr);
22381 }
22382
22383 if((uint32_t)t!=strlen(tmpstr))
22384 {
22385 new_t=t+1;
22386 }
22387 else
22388 {
22389 new_t=-1;
22390 }
22391
22392 temp = tmpstr[t];
22393 tmpstr[t]=0;
22394 maxlen=zc_max(maxlen,text_length(f, tmpstr));
22395 tmpstr[t]=temp;
22396
22397 if(new_t!=-1)
22398 {
22399 tmpstr+=new_t;
22400 }
22401 else break;
22402 }
22403 return maxlen;
22404 }
22405
22406 int32_t count_lines(char const* str)
22407 {
22408 int32_t count=1;
22409
22410 for(word i=0; i<strlen(str); ++i)
22411 {
22412 if(str[i]=='\n')
22413 {
22414 ++count;
22415 }
22416 }
22417
22418 return count;
22419 }
22420
22421 void textbox_out(BITMAP* dest, FONT* font, int x, int y, int fg, int bg, char const* str, int align, size_and_pos* dims)
22422 {
22423 static size_and_pos nilsz;
22424 size_and_pos& txbox = dims ? *dims : nilsz;
22425
22426 char* kill = (char*)malloc(strlen(str)+1);
22427 char *tmpstr = kill;
22428 strcpy(tmpstr,str);
22429
22430 while(tmpstr[0] == '\n')
22431 ++tmpstr;
22432 int len = strlen(tmpstr);
22433 while(tmpstr[len-1] == '\n')
22434 tmpstr[--len] = 0;
22435
22436 txbox.x=x;
22437 txbox.y=y;
22438 int32_t lines=count_lines(tmpstr);
22439 txbox.w = 1;
22440 txbox.h = lines;
22441 txbox.xscale = get_longest_line_length(font, tmpstr);
22442 txbox.yscale = text_height(font);
22443
22444 int ax = 0; //Aligned x
22445 switch(align)
22446 {
22447 case 0: //left
22448 break;
22449 case 1: //center
22450 txbox.x -= txbox.xscale/2;
22451 ax = txbox.xscale/2;
22452 break;
22453 case 2: //right
22454 txbox.x -= txbox.xscale;
22455 ax = txbox.xscale;
22456 break;
22457 }
22458
22459 int bw = txbox.w*txbox.xscale;
22460 int bh = txbox.h*txbox.yscale;
22461 BITMAP* outbmp = create_bitmap_ex(8, bw, bh);
22462 clear_to_color(outbmp, bg);
22463
22464 char temp = 0;
22465 int32_t t=0;
22466 int32_t new_t=-1;
22467 int32_t line=0;
22468
22469 while(tmpstr[t])
22470 {
22471 t=strchrnum(tmpstr, '\n');
22472
22473 if(t==-1)
22474 t=(int32_t)strlen(tmpstr);
22475
22476 if((uint32_t)t!=strlen(tmpstr))
22477 new_t=t+1;
22478 else
22479 new_t=-1;
22480
22481 temp = tmpstr[t];
22482 tmpstr[t]=0;
22483 gui_textout_ln(outbmp, font, (ucc*)tmpstr, ax, (line*txbox.yscale), fg, -1, align);
22484 tmpstr[t]=temp;
22485 ++line;
22486
22487 if(new_t!=-1)
22488 {
22489 tmpstr+=new_t;
22490 t=0;
22491 }
22492 }
22493
22494 blit(outbmp, dest, 0, 0, txbox.x, txbox.y, bw, bh);
22495 destroy_bitmap(outbmp);
22496 free(kill);
22497 }
22498
22499 void highlight_sqr(BITMAP* dest, int color, int x, int y, int w, int h, int thick)
22500 {
22501 for(int q = 0; q < thick; ++q)
22502 {
22503 safe_rect(dest, x+q, y+q, x+w-1-q, y+h-1-q, color);
22504 }
22505 }
22506 void highlight_sqr(BITMAP* dest, int color, size_and_pos const& rec, int thick)
22507 {
22508 highlight_sqr(dest, color, rec.x, rec.y, rec.tw(), rec.th(), thick);
22509 }
22510 void highlight_frag(BITMAP* dest, int color, int x1, int y1, int w, int h, int fw, int fh, int thick)
22511 {
22512 int xc = x1+fw-1;
22513 int yc = y1+fh-1;
22514 int x2 = x1+w-1;
22515 int y2 = y1+h-1;
22516
22517 hline(dest, x1, y1, x2, color);
22518 vline(dest, x1, y1, y2, color);
22519
22520 hline(dest, x1, y2, xc, color);
22521 vline(dest, x2, y1, yc, color);
22522 hline(dest, xc, yc, x2, color);
22523 vline(dest, xc, yc, y2, color);
22524 }
22525 void highlight_frag(BITMAP* dest, int color, size_and_pos const& rec, int thick)
22526 {
22527 highlight_frag(dest, color, rec.x, rec.y, rec.tw(), rec.th(), rec.fw, rec.fh, thick);
22528 }
22529
22530 void highlight(BITMAP* dest, size_and_pos& hl)
22531 {
22532 if(hl.fw > -1 && hl.fh > -1)
22533 {
22534 highlight_frag(dest, hl.data[1], hl, hl.data[0]);
22535 }
22536 else highlight_sqr(dest, hl.data[1], hl, hl.data[0]);
22537 }
22538
22539 std::pair<int, int> get_box_text_size(char const* tipmsg, double txscale)
22540 {
22541 if(txscale < 1) txscale = 1;
22542 char* kill = (char*)malloc(strlen(tipmsg)+1);
22543 char *tmpstr = kill;
22544 strcpy(tmpstr,tipmsg);
22545
22546 while(tmpstr[0] == '\n')
22547 ++tmpstr;
22548 int len = strlen(tmpstr);
22549 while(tmpstr[len-1] == '\n')
22550 tmpstr[--len] = 0;
22551
22552 int32_t lines = count_lines(tmpstr);
22553 int txlen = get_longest_line_length(font, tmpstr);
22554 int txhei = lines*text_height(font);
22555 int tx_sclen = (txlen * txscale);
22556 int tx_schei = (txhei * txscale);
22557 int w = tx_sclen + 8 + 1;
22558 int h = tx_schei + 8 + 1;
22559 if (w > zq_screen_w)
22560 w = zq_screen_w;
22561 if (h > zq_screen_h)
22562 h = zq_screen_h;
22563 return {w, h};
22564 }
22565
22566 void draw_box(BITMAP* destbmp, size_and_pos* pos, char const* tipmsg, double txscale)
22567 {
22568 if(txscale < 1) txscale = 1;
22569 char* kill = (char*)malloc(strlen(tipmsg)+1);
22570 char *tmpstr = kill;
22571 strcpy(tmpstr,tipmsg);
22572
22573 while(tmpstr[0] == '\n')
22574 ++tmpstr;
22575 int len = strlen(tmpstr);
22576 while(tmpstr[len-1] == '\n')
22577 tmpstr[--len] = 0;
22578
22579 auto& box = *pos;
22580 clear_bitmap(destbmp);
22581
22582 int32_t lines=count_lines(tmpstr);
22583 int txlen = get_longest_line_length(font, tmpstr);
22584 int txhei = lines*text_height(font);
22585 int tx_sclen = (txlen * txscale);
22586 int tx_schei = (txhei * txscale);
22587 box.w = tx_sclen + 8 + 1;
22588 box.h = tx_schei + 8 + 1;
22589 if (box.w > zq_screen_w)
22590 box.w = zq_screen_w;
22591 if (box.h > zq_screen_h)
22592 box.h = zq_screen_h;
22593
22594 if(box.x+box.w>=zq_screen_w)
22595 {
22596 box.x=(zq_screen_w - box.w);
22597 }
22598
22599 if(box.y+box.h>=zq_screen_h)
22600 {
22601 box.y=(zq_screen_h - box.h);
22602 }
22603
22604 rectfill(destbmp, 1, 1, box.w-3, box.h-3, jwin_pal[jcTEXTBG]);
22605 rect(destbmp, 0, 0, box.w-2, box.h-2, jwin_pal[jcTEXTFG]);
22606 vline(destbmp, box.w-1, 0, box.h-1, jwin_pal[jcTEXTFG]);
22607 hline(destbmp, 1, box.h-1, box.w-2, jwin_pal[jcTEXTFG]);
22608 destbmp->line[box.h-1][0]=0;
22609 destbmp->line[0][box.w-1]=0;
22610
22611 char temp = 0;
22612 int32_t t=0;
22613 int32_t new_t=-1;
22614 int32_t line=0;
22615
22616 BITMAP* txbmp = create_bitmap_ex(8,box.w,box.h);
22617 clear_bitmap(txbmp);
22618 while(tmpstr[t])
22619 {
22620 t=strchrnum(tmpstr, '\n');
22621
22622 if(t==-1)
22623 {
22624 t=(int32_t)strlen(tmpstr);
22625 }
22626
22627 if((uint32_t)t!=strlen(tmpstr))
22628 {
22629 new_t=t+1;
22630 }
22631 else
22632 {
22633 new_t=-1;
22634 }
22635
22636 temp = tmpstr[t];
22637 tmpstr[t]=0;
22638 textprintf_ex(txbmp, font, 0, (line*text_height(font)), jwin_pal[jcTEXTFG], -1, "%s", tmpstr);
22639 tmpstr[t]=temp;
22640 ++line;
22641
22642 if(new_t!=-1)
22643 {
22644 tmpstr+=new_t;
22645 t=0;
22646 }
22647 }
22648 masked_stretch_blit(txbmp,destbmp,0,0,txlen,txhei,4,4,tx_sclen,tx_schei);
22649 destroy_bitmap(txbmp);
22650 free(kill);
22651 }
22652
22653 void update_tooltip(int32_t x, int32_t y, size_and_pos const& sqr, char const* tipmsg, double scale)
22654 {
22655 update_tooltip(x,y,sqr.x,sqr.y,sqr.w*sqr.xscale,sqr.h*sqr.yscale,tipmsg,sqr.fw,sqr.fh,scale);
22656 }
22657 void update_tooltip(int32_t x, int32_t y, int32_t tx, int32_t ty, int32_t tw, int32_t th, char const* tipmsg, int fw, int fh, double scale)
22658 {
22659 if(!EnableTooltips)
22660 {
22661 return;
22662 }
22663
22664 ttip_install(ttip_global_id, tipmsg, tx, ty, tw, th, x, y, fw, fh);
22665 }
22666
22667 void ZQ_ClearQuestPath()
22668 {
22669 zc_set_config("zquest","win_last_quest",(char const*)nullptr);
22670 strcpy(filepath,"");
22671 }
22672
22673 //FFCore
22674
22675 void FFScript::init(bool for_continue)
22676 {
22677 for ( int32_t q = 0; q < wexLast; q++ ) warpex[q] = 0;
22678 numscriptdraws = 0;
22679 max_ff_rules = qr_MAX;
22680 temp_no_stepforward = 0;
22681 nostepforward = 0;
22682
22683 coreflags = 0;
22684 skip_ending_credits = 0;
22685 music_update_cond = 0;
22686 music_update_flags = 0;
22687 for ( int32_t q = 0; q < susptLAST; q++ ) { system_suspend[q] = false; }
22688
22689 //for ( int32_t q = 0; q < 512; q++ ) FF_rules[q] = 0;
22690 int32_t usr_midi_volume = usr_digi_volume = usr_sfx_volume = usr_music_volume = usr_panstyle = 0;
22691 FF_hero_action = 0;
22692 enemy_removal_point[spriteremovalY1] = -32767;
22693 enemy_removal_point[spriteremovalY2] = 32767;
22694 enemy_removal_point[spriteremovalX1] = -32767;
22695 enemy_removal_point[spriteremovalX2] = 32767;
22696 enemy_removal_point[spriteremovalZ1] = -32767;
22697 enemy_removal_point[spriteremovalZ2] = 32767;
22698
22699 for ( int32_t q = 0; q < 4; q++ )
22700 {
22701 FF_screenbounds[q] = 0;
22702 FF_screen_dimensions[q] = 0;
22703 FF_subscreen_dimensions[q] = 0;
22704 FF_eweapon_removal_bounds[q] = 0;
22705 FF_lweapon_removal_bounds[q] = 0;
22706 }
22707 for ( int32_t q = 0; q < FFSCRIPTCLASS_CLOCKS; q++ )
22708 {
22709 FF_clocks[q] = 0;
22710 }
22711 for ( int32_t q = 0; q < SCRIPT_DRAWING_RULES; q++ )
22712 {
22713 ScriptDrawingRules[q] = 0;
22714 }
22715 for ( int32_t q = 0; q < NUM_USER_MIDI_OVERRIDES; q++ )
22716 {
22717 FF_UserMidis[q] = 0;
22718 }
22719 subscreen_scroll_speed = 0; //make a define for a default and read quest override! -Z
22720 kb_typing_mode = false;
22721 initIncludePaths();
22722 }
22723
22724 void FFScript::updateIncludePaths()
22725 {
22726 includePaths.clear();
22727 int32_t pos = 0; int32_t pathnumber = 0;
22728 for ( int32_t q = 0; includePathString[pos]; ++q )
22729 {
22730 int32_t dest = 0;
22731 char buf[2048] = {0};
22732 while(includePathString[pos] != ';' && includePathString[pos])
22733 {
22734 buf[dest] = includePathString[pos];
22735 ++pos;
22736 ++dest;
22737 }
22738 ++pos;
22739 string str(buf);
22740 includePaths.push_back(str);
22741 }
22742 }
22743
22744 void FFScript::initIncludePaths()
22745 {
22746 memset(includePathString,0,sizeof(includePathString));
22747 FILE* f = fopen("includepaths.txt", "r");
22748 if(f)
22749 {
22750 int32_t pos = 0;
22751 int32_t c;
22752 do
22753 {
22754 c = fgetc(f);
22755 if(c!=EOF)
22756 includePathString[pos++] = c;
22757 }
22758 while(c!=EOF && pos<MAX_INCLUDE_PATH_CHARS);
22759 if(pos<MAX_INCLUDE_PATH_CHARS)
22760 includePathString[pos] = '\0';
22761 includePathString[MAX_INCLUDE_PATH_CHARS-1] = '\0';
22762 fclose(f);
22763 }
22764 else strcpy(includePathString, "include/;headers/;scripts/;");
22765 al_trace("Full path string is: ");
22766 safe_al_trace(includePathString);
22767 al_trace("\n");
22768 updateIncludePaths();
22769
22770 for ( size_t q = 0; q < includePaths.size(); ++q )
22771 {
22772 al_trace("Include path %zu: ",q);
22773 safe_al_trace(includePaths.at(q).c_str());
22774 al_trace("\n");
22775 }
22776 }
22777
22778 int32_t FFScript::getQRBit(int32_t rule)
22779 {
22780 return ( get_qr(rule) ? 1 : 0 );
22781 }
22782
22783 int32_t FFScript::getTime(int32_t type)
22784 {
22785 //struct tm *tm_struct = localtime(time(NULL));
22786 struct tm * tm_struct;
22787 time_t rawtime;
22788 time (&rawtime);
22789 tm_struct = localtime (&rawtime);
22790
22791 switch(type)
22792 {
22793 case curyear:
22794 {
22795 int32_t year = tm_struct->tm_year + 1900; /* year */
22796 //year format starts at 1900, so we add it to the return
22797 return year;
22798
22799 }
22800 case curmonth:
22801 {
22802 int32_t month = tm_struct->tm_mon +1; /* month */
22803 //Months start at 0, but we want 1->12
22804 return month;
22805 }
22806 case curday_month:
22807 {
22808 int32_t day_month = tm_struct->tm_mday; /* day of the month */
22809 return day_month;
22810 }
22811 case curday_week:
22812 {
22813 int32_t day_week = tm_struct->tm_wday; /* day of the week */
22814 return day_week;
22815 }
22816 case curhour:
22817 {
22818 int32_t hour = tm_struct->tm_hour; /* hours */
22819 return hour;
22820 }
22821 case curminute:
22822 {
22823 int32_t minutes = tm_struct->tm_min; /* minutes */
22824 return minutes;
22825 }
22826 case cursecond:
22827 {
22828 int32_t secs = tm_struct->tm_sec; /* seconds */
22829 return secs;
22830 }
22831 case curdayyear:
22832 {
22833 int32_t day_year = tm_struct->tm_yday; /* day in the year */
22834 return day_year;
22835 }
22836 case curDST:
22837 {
22838 int32_t isDST = tm_struct->tm_isdst; /* daylight saving time */
22839 return isDST;
22840 }
22841 default: return -1;
22842
22843 }
22844 }
22845
22846 extern const char *itemclass_help_string_defaults[itype_max];
22847
22848 /* end */
22849
22850 24576 int32_t FFScript::getQuestHeaderInfo(int32_t type)
22851 {
22852 24576 return quest_format[type];
22853 }
22854
22855 bool isSideViewGravity(int32_t t)
22856 {
22857 return (Map.CurrScr()->flags7&fSIDEVIEW) != 0;
22858 }
22859
22860
22861
22862
22863 void FFScript::ZScriptConsole(bool open)
22864 {
22865
22866
22867 #ifdef _WIN32
22868 if ( console_is_open )
22869 {
22870 zscript_coloured_console.Create("ZQuest Classic Logging Console", 600, 200);
22871 zscript_coloured_console.cls(CConsoleLoggerEx::COLOR_BACKGROUND_BLACK);
22872 zscript_coloured_console.gotoxy(0,0);
22873 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
22874 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"ZQuest Classic Logging Console\n");
22875 }
22876 else
22877 {
22878 //close
22879 zscript_coloured_console.Close();
22880 }
22881 #endif
22882 }
22883
22884 template <typename ...Params>
22885 void FFScript::ZScriptConsole(int32_t attributes,const char *format, Params&&... params)
22886 {
22887 #ifdef _WIN32
22888 initConsole();
22889 zscript_coloured_console.cprintf( attributes, format, std::forward<Params>(params)... );
22890 #endif
22891 }
22892
22893 int32_t getpitfall(int32_t x, int32_t y){return 0;}
22894
22895 bool update_hw_pal = false;
22896 void update_hw_screen()
22897 {
22898 if (is_headless())
22899 return;
22900
22901 framecnt++;
22902
22903 zc_process_display_events();
22904 if (update_hw_pal)
22905 {
22906 zc_set_palette(RAMpal);
22907 update_hw_pal = false;
22908 }
22909
22910 render_timer_wait();
22911 render_zq();
22912 }
22913
22914 bool checkCost(int32_t ctr, int32_t amnt)
22915 {
22916 if(!game) return true;
22917 if(amnt <= 0) return true;
22918 switch (ctr)
22919 {
22920 case crMONEY: //rupees
22921 {
22922 if ( current_item_power(itype_wallet) ) return true;
22923 break;
22924 }
22925 case crMAGIC: //magic
22926 {
22927 if (get_qr(qr_ENABLEMAGIC))
22928 {
22929 return (((current_item_power(itype_magicring) > 0)
22930 ? game->get_maxmagic()
22931 : game->get_magic()+game->get_dmagic())>=amnt*game->get_magicdrainrate());
22932 }
22933 return true;
22934 }
22935 case crARROWS:
22936 {
22937 if(current_item_power(itype_quiver))
22938 return true;
22939 if(!get_qr(qr_TRUEARROWS))
22940 return checkCost(crMONEY, amnt);
22941 break;
22942 }
22943 case crBOMBS:
22944 {
22945 if(current_item_power(itype_bombbag))
22946 return true;
22947 break;
22948 }
22949 case crSBOMBS:
22950 {
22951 if(current_item_power(itype_bombbag)
22952 && itemsbuf[current_item_id(itype_bombbag)].flags & item_flag1)
22953 return true;
22954 break;
22955 }
22956 }
22957 return (game->get_counter(ctr)+game->get_dcounter(ctr)>=amnt);
22958 }
22959 bool checkmagiccost(int32_t itemid, bool checkTime)
22960 {
22961 if(itemid < 0)
22962 {
22963 return false;
22964 }
22965 itemdata const& id = itemsbuf[itemid];
22966 return checkCost(id.cost_counter[0], id.cost_amount[0])
22967 && checkCost(id.cost_counter[1], id.cost_amount[1]);
22968 }
22969 bool checkbunny(int32_t itemid)
22970 {
22971 return true;
22972 }
22973
22974 void payCost(int32_t ctr, int32_t amnt, int32_t tmr, bool ignoreTimer)
22975 {
22976 return;
22977 }
22978 void paymagiccost(int32_t itemid, bool ignoreTimer, bool onlyTimer)
22979 {
22980 return;
22981 }
22982 bool is_in_scrolling_region()
22983 {
22984 return false;
22985 }
22986
22987 void enter_sys_pal(){}
22988 void exit_sys_pal(){}
22989
22990 void replay_step_comment(std::string comment) {}
22991 bool replay_is_active() {return false;}
22992 9 bool replay_is_replaying() {return false;}
22993 bool replay_version_check(int min, int max) {return max == -1;}
22994 bool replay_is_debug() {return false;}
22995 std::string replay_get_meta_str(std::string key){return "";}
22996 int32_t item::run_script(int32_t mode){return 0;};
22997 ffcdata* slopes_getFFC(int id)
22998 {
22999 return nullptr;
23000 }
23001
23002 int calculate_test_dmap()
23003 {
23004 int dmap = -1;
23005 auto pal = Map.getcolor();
23006 int scr = Map.getCurrScr();
23007 int scrx = scr & 0x0F;
23008 for(auto q = 0; q < MAXDMAPS; ++q)
23009 {
23010 auto& dm = DMaps[q];
23011 if(dm.map != Map.getCurrMap())
23012 continue;
23013 if((dm.type&dmfTYPE)!=dmOVERW)
23014 {
23015 if(scrx < dm.xoff || scrx >= dm.xoff+8)
23016 continue;
23017 }
23018 if(dmap < 0)
23019 dmap = q; // soft-accept this, but look for better still
23020 if(pal == dm.color)
23021 {
23022 dmap = q;
23023 // found the best match we have information for, break out
23024 break;
23025 }
23026 }
23027 if(dmap < 0) dmap = 0;
23028 return dmap;
23029 }
23030
23031 #ifdef __EMSCRIPTEN__
23032 extern "C" void open_test_mode()
23033 {
23034 int dmap = calculate_test_dmap();
23035 int scr = zc_min(0x7F, Map.getCurrScr());
23036
23037 em_open_test_mode(filepath, dmap, scr, -1);
23038 }
23039
23040 extern "C" void get_shareable_url()
23041 {
23042 EM_ASM({
23043 ZC.setShareableUrl({open: UTF8ToString($0), map: $1, screen: $2});
23044 }, filepath, Map.getCurrMap(), Map.getCurrScr());
23045 }
23046 #endif
23047
23048 11 void setZScriptVersion(int32_t v){}
23049